数字和字符的内存储和表示
1 简介
本文简单展示了 Go 里面 数值、字符(本质上也是数值)、变量在内存里的管理方式,以及和字符串/UTF-8 表达方式的差异。
以下可以从几个角度拆开来看:
2. 数字在内存里的表达和管理
在 Go 里,像 int、float64、byte 等基本数值类型都有固定的内存宽度,例如:
int 在 64 位系统通常是 8 字节(64bit)
int32 就是 4 字节
float64 就是 8 字节
byte 等价于 uint8,就是 1 字节
所以 :
b := 42
a := 43
编译器会在栈上为 a 和 b 各分配一块固定大小的内存(比如 8 字节),地址可以用 &a 取到。你看到的 fmt.Printf(“%d\n”, &a) 打印出的就是内存地址。
- 特点:
定长存储:数字的存储大小固定(编译期已知),所以内存地址管理很高效。
连续栈分配:在 main 函数里,这些局部变量一般是按顺序分配在栈上,所以你会看到 &a, &b, &c… 地址是紧挨着的。
值语义:数字变量传参时会复制值,除非你显式传指针(比如 square 函数那一例)。
3. 字符和 UTF-8 在 Go 中的区别
Go 的 string 本质上是 只读的字节切片,底层表示是:
type string struct {
data *byte // 指向底层字节数组
len int // 字符串长度(字节数,不是字符数)
}
如果是 ASCII 字符(‘a’、‘Z’),其实只占 1 字节。
如果是 中文/emoji,按照 UTF-8 编码,一个字符可能占 3~4 字节。
所以字符串长度 len(“你好”) 是 6,不是 2。
- 特点:
变长存储:UTF-8 每个字符所需字节不固定。
堆分配:字符串字节数组通常在堆上分配,string 结构体(data 指针和长度)在栈上。
需要解码:遍历字符串要解码 UTF-8,Go 提供了 for range 直接解码成 rune(相当于 int32)。
4. 数值 vs UTF-8 存储效率对比
数值(int、float、byte)
内存大小固定,地址计算简单。
更适合数值计算和密集存储(比如数组 [1000000]int 直接一块连续内存)。
字符串(UTF-8)
存储大小不固定,取决于字符内容。
适合节省内存(英文占 1 字节,中文占 3 字节),但需要额外的指针和长度管理。
访问单个字符需要解码,开销比整数大。
5. 结合 三个例子分析
b := 42
a := 43
c := 44
d := 255
e := 256
f := 355650
fmt.Println("a - ", a)
fmt.Println("a's memory address - ", &a, unsafe.Pointer(&a))
fmt.Printf("%d \n", &a) //整数显示
fmt.Println("b's memory address - ", b, &b, unsafe.Pointer(&b))
fmt.Printf("%d \n", &b) //整数显示
fmt.Println("c's memory address - ", c, &c, unsafe.Pointer(&c))
fmt.Printf("%d \n", &c) //整数显示
fmt.Println("d's memory address - ", d, &d, unsafe.Pointer(&d))
fmt.Printf("%d \n", &d) //整数显示
fmt.Println("e's memory address - ", e, &e, unsafe.Pointer(&e))
fmt.Printf("%d \n", &e) //整数显示
fmt.Println("f's memory address - ", f, &f, unsafe.Pointer(&f))
fmt.Printf("%d \n", &f) //整数显示
返回指针
func square(x int) *int {
y := x * x
return &y
}
这里 y 是局部变量,按理说函数结束后应该销毁。但 Go 编译器会做 逃逸分析,发现 y 的地址被返回了,所以会把 y 分配到堆上(而不是栈上),保证外部还能用。
- 这也说明 Go 的内存管理不是一成不变的,会根据编译器分析结果决定分配在栈还是堆。
6 小结
数字类型(int/float/byte):定长存储,地址连续,访问速度快,内存管理简单 → 比 UTF-8 更高效。
字符串/UTF-8:变长存储,需要额外的解码和指针管理,更灵活,但在性能上不如数值固定内存表示。
- 因此:
涉及大量计算/固定大小数据结构 → 数字存储更高效。
涉及文本/多语言 → UTF-8 更节省空间,但有解码成本。
- 点赞
- 收藏
- 关注作者
评论(0)