携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第2天,点击查看活动详情
什么变量的大小是0字节
- 使用unsafe.Sizeof 方法可以拿到当前变量的大小
运行结果为 8 ,经过测试可以发现 int uint 以及 指针 是和系统字长有关系的,在64位系统上的大小是8个字节,在32位系统上是4个字节
- 空结构体的大小为0
通过运行会发现空结构体不占用空间没有大小,而且所有空结构体的地址一样
在malloc.go中可以找到 zerobase:所有0字节的地址集合
- 注意:只有空结构体独立出现时地址才会是 zerobase
执行之后会发现 k结构体的地址已经不再是 zerobase 并且大小已经不再是0而是8
空结构体的应用
- 实现set:只有key 没有 value
- 通道:发送信号不携带任何信息
如何正确查看字符串的长度
- 通过sizeof查看到的是字符串的指针 为16字节
- 在string.go 下stringStruct 就是string的底层结构
str 指针指向底层Byte数组
len 表述Byte数组的长度
字符编码问题
- 所有字符均使用 unicode字符集
- 使用 UTF-8 编码
Unicode
- 一种统一的字符集
- 包括了159种文字的144679个字符
- 14万个字符至少需要3个字节表示
- 英文字母均排在前128个
UTF-8
- Unicode 的一种变长格式
- 128个 US-ASCii 字符只需一个字节编码
- 西方常用字符需要两个字节
- 其他字符需要三个字节,极少需要四个字节
遍历 字符串
在 utf8.go 中有其实现 range遍历时,被解码成 rune 类型的字符
字符串的切分
- 需要且分时
- 转为rune数组
- 切片
- 转为string
s = string([]rune(s)[:3])
切片
- 切片的长度都是 24位(64位系统)
- array 数组的地址,len 切片的长度,cap 切片的容量
切片的创建
- 根据数组创建
arr[0:3]- 字面量:编译时插入创建数组的代码(先创建数组,再创建slice)
slice := []int{1,2,3}- make:运行时创建数组
slice := make([]int,10)
观察通过字面量的方式底层是如何运行的
测试代码
func main() {
s := []int{6, 7, 8}
fmt.Println(s)
}
go build -gcflags -S main.go
- 在编译时先是创建一个长度为3的int数组
- 将字面量6,7,8插入到数组中
- 根据数组创建slice
切片的追加
- 不扩容时,只调整len(编译器负责)
- 扩容时,编译时转为调用runtime.growslice()
- 新建一个数组
- 如果期望容量大当前容量的2倍,就是使用期望容量
- 如果当前切片的长度小于1024,将翻倍
- 如果大于1024,每次增加 25%