数据类型
字符串
字符串在 Go 中是不可变类型。string本质是一个结构体底层是由 str 指针和 len 组成。
type stringStruct struct {
str unsafe.Pointer
len int
}
string 与 []byte 转换会发生内存拷贝?
- byte 是unit8 别名
- string本质是一个结构体底层是由 str 指针 和 len 组成。一个byte类型数组
- string 类型是不能更改。但stringStruct 中str 指针可以改变,指向的内容不可变。可以看出来,指针指向的位置发生了变化,也就是每更改一次字符串,就需要重新分配一次内存,之前分配的空间会被gc;
- 将string的底层数组从头部复制n个到[]byte对应的底层数组中去,预先定义一个长度为32的数组,字符串的长度超过了这个数组的长度,就重新分配一块内存,否则就是用预先分配的内存来做
- 标准方法发生内存拷贝,更安全
字符串拼接性能
- +操作符:
- 优点: 语法简单,直观易懂。
- 缺点: 在大量字符串拼接时,每次 + 操作都会创建新的字符串对象,会引发多次内存分配和复制,性能较差。 时间复杂度为 O(n^2),因为每次都要复制整个字符串。
str := "Hello, " + "world!" - strings.Join() 函数:
- 优点: 使用 strings.Join() 函数进行拼接,只需要遍历一次待拼接的字符串数组,内存分配和复制次数较少,性能较好。
- 缺点: 需要将字符串数组转换为切片,有一定的性能开销。
strs := []string{"Hello", "world", "!"} result := strings.Join(strs, " ")
时间复杂度为 O(n),其中 n 是所有字符串的总长度。
-
fmt.Sprintf() 函数:
- 优点: 支持格式化输出,可以方便地构建复杂的格式化字符串。 由于 fmt.Sprintf() 是一次性完成字符串拼接的,因此对于少量字符串拼接时性能较好。
- 缺点: 对于大量的字符串拼接,由于每次调用 fmt.Sprintf() 都会创建新的字符串对象,因此性能较差。 时间复杂度取决于字符串的总长度。
name := "John" age := 30 str := fmt.Sprintf("Name: %s, Age: %d", name, age) -
strings.Builder 类型:
- 优点: 在循环中进行字符串拼接时性能优于其他方法。 strings.Builder 类型内部使用了缓冲区,避免了频繁的内存分配和复制,因此性能较好。
- 缺点: 语法相对复杂,不如其他方法直观易懂。
var builder strings.Builder for i := 0; i < 10; i++ { builder.WriteString("Iteration ") builder.WriteString(strconv.Itoa(i)) builder.WriteString("\n") } result := builder.String()
综上所述,性能最优的字符串拼接方法取决于具体的场景和需求。对于大量字符串拼接的情况,strings.Builder 是性能最好的选择;对于少量且需要格式化的情况,fmt.Sprintf() 是一个不错的选择;而对于简单的拼接操作,strings.Join() 通常也能满足需求。尽管 + 操作符简单直观,但在大量拼接时会导致性能问题,应尽量避免在性能敏感的代码中使用。
数字类型
- int,uint
- int8,uint8
- int16,uint16
- int32,uint32
- int64,uint64
- float32
- float64
- complex64
- complex128
rune 类型
- rune int32 别名
- 一个 rune值代表一个 Unicode字符
uintptr
array 类型
- len() == cap()
- 数组是单一内存块,并无其他附加结构
- 初始化多维数组,仅第一维度允许用
... - 支持数字指针直接访问
- 直接获取元素指针
- 值传递,复制整个数组 指针
- 数组指针:
&array指向整个数组的指针 - 元素指针:
&array[0]指向某个元素指针 - 指针数组:
[...]*int{&a, &b}元素是指针的数组 复制 - 数组传递会复制整个数组,可用指针或切片代替
nil
- 两个nil 不能比较,nil 是无类型
- 声明一个nil 的Map,可读不可写
- 关闭nil的channel 会panic
- nil 切片不能索引访问
- 方法接受者是nil, 调用方法也会panic
- 空指针是一个灭有任何值的指针