Jason-Yuan

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

go语言知识点 --主要针对与C++的区别


一、大括号与分号问题

分号跟在特定符号后面的换行符会被替换为分号,这会导致几个问题,说明如下:

  1. for、if 语句必须有大括号,独立语句也必须用大括号括起来。
    if a:=1; a>0 {
        a--;
    }

    if a==0 a++     // 编译失败
  1. "{" 必须和 for、if、func 等关键字在同一行,否则编译无法通过
    if a:=1; a>0 
    {   // 编译失败
        a--;
    }
  1. else 必须与 if 的 } 在同一行,同: }else{
    if a:=1; a>0{
        a--;
    }
    else{   // 编译失败
    }

二、格式化打印以及转义字符

  1. f系列函数支持格式化打印,包括:fmt.Printf,log.Printf, fmt.Errorf 等
  2. ln系列函数不含格式化串,但可以直接输出、添加空格、自动换行,如:fmt.println
  3. 转义符 %c 支持单独unicode汉字
  4. 转义符 %t 打印true/false串
  5. 转义符 %v 可以使用默认格式显示任意类型的值,如数组或map类型, 带[ ]
    alt text

三、字符串操作

  1. 使用 + 可以为追加字符串,但是每次追加都会分配和释放内存
    var s string
    s += "aaa"
    s = s + "bbb"
  1. 使用 strings.join 可以避免内存分配,提高效率
	s := "hello"
	fmt.Println(strings.Join([]string{s, "aaa", "bbb"}, ","))

// 输出:
// hello,aaa,bbb   

strings.Join函数将数组中的成员一次性连接成sring,可以给出字符串之间的分割符。

  1. 与 strings.join 对应的是 strings.split
	s := "hello,aaa,bbb"
    ss := strings.Split(s, ",")
	fmt.Println(ss)

// 输出:
// [hello aaa bbb]

四、函数或实体的声明

  1. 函数和其他包级别的实体可以以任意次序声明, 对函数的调用可以出现在其声明之前。

五、随机数生成器

GO语言1.20版本之后采用新的随机数生成器简化用法并提高安全性,避免了旧版本手动用时间播种时,在短时间内多次运行程序时,可能因时间戳相同导致随机序列重复。在 1.20 以前的go版本,生成随机数之前,会调用时间播种,然后获取随机数。

    rand.Seed(time.Now().UTC().UnixNano())
    fmt.Println(rand.Intn(100)) // 生成 0-99 的随机整数
    fmt.Println(rand.Float64()) // 生成 0.0-1.0 的随机浮点数

从1.20版本开始,全局生成器会自动初始化,且每次程序运行都会生成不同的随机序列。用户在生成随机数之前无需播种,直接调用即可。

    //rand.Seed(time.Now().UTC().UnixNano())
    fmt.Println(rand.Intn(100)) // 生成 0-99 的随机整数
    fmt.Println(rand.Float64()) // 生成 0.0-1.0 的随机浮点数

只有需要生成可复现随机数,才需要播种,但是需要创建一个新实例,而不是用全局的随机数生成器。自定义实例不会影响全局生成器的状态。

    // 手动指定种子(如用时间戳,或固定值如 42 用于复现)
    source := rand.NewSource(time.Now().UnixNano())
    r := rand.New(source) // 创建自定义随机数生成器

    // 使用自定义生成器生成随机数
    fmt.Println(r.Intn(100))
    fmt.Println(r.Float64())
posted on 2025-08-05 21:16  12yuan  阅读(9)  评论(0)    收藏  举报