[Golang 修仙之路] Go基础:字符串底层实现

50 阅读2分钟

声明

本文是本人学习Go语言的学习笔记,并非原创。

字符集 && 编码方式

数字 可以 直接用二进制表示,但是字符就没那么容易,所以就有了「字符集」。

字符集 其实就是 字符与对应数字的映射关系,常见的字符集有:ASCII,GBK,unicode

有了字符集,字符可以用二进制表示了,但是「字符串」还是不行,原因是,没有解决“如何确定字符串中每个字符的边界”

这就需要:编码方式。

常见的编码方式有:

  • 定长编码:字符集中最大的编号,需要用多少位二进制表示,每个字符就都用这么多位表示,前位补0即可。
  • 编码模板:开头为0,说明编号范围在[0,127];开头为10 ... ; 开头为110,...

image.png

有了字符集 + 编码方式,就可以用二进制表示字符串了。

Go语言默认的编码方式是:UTF-8

Go 字符串

Go语言的字符串,底层保存了一个指向字符串首地址的指针,还保存了字符串占用的字节数len。因此Go的字符串是二进制安全的。

Go语言中,可以用s[i]读字符串中的byte,但是不能s[i]='x'这样修改字符串。

此图展示了改字符串会发生编译错误 image.png

因为Go认为字符串常量是不可修改的,因此编译器会把字符串常量分配到「只读」的内存空间。

Go的字符串可以共用底层字符串内容:

image.png

如果想要修改字符串,可以将字符串类型转换为字节slice类型,这样编译器会为字节数组分配一段新的内存空间,并把字符串中的每个字符都拷贝到新的数组中。其实可以通过unsafe让slice仍然指向原先字符串的内存,这样即便转换了类型,依然不能修改这段只读内存的内容。