字符和数字的映射表就是字符集。utf-8是unicode字符集的一种。
定长编码:取32字节定长 -> 浪费内存
go是如何编码的?
go采用的是utf-8编码,utf-8采用变长编码方案:
- U+0000 至 U+007F:
0xxxxxxx
- U+0080 至 U+07FF:
110xxxxx 10xxxxxx
- U+0800 至 U+FFFF:
1110xxxx 10xxxxxx 10xxxxxx
- U+10000 至 U+10FFFF:
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
其中x
表示有效数据位,10
开头的字节被称为继续字节(continuation bytes),用于扩展字符的编码空间。举几个例子:
- ASCII字符'A'(U+0041)在UTF-8中编码为:
01000001
- Unicode字符'€'(U+20AC)在UTF-8中编码为:
11100010 10000010 10101100
- Unicode字符'😀'(U+1F600)在UTF-8中编码为:
11110000 10011110 10011000 10000000
go1.22是如何存取字符串的?
首先说c是如何存储字符串的,字符串标识指向一个内存地址,取字符串时会一直读取到\x00
,这也就限制了c字符串中不允许出现\x00
。
go在底层定义的string的数据结构为:
type stringStruct struct {
str unsafe.Pointer // 指向字符串首地址的指针
len int // 字符串的字节长度,而不是字符长度
}
如何脱离只读内存的限制?
go认为字符串是只读类型,那如何脱离只读内存的限制呢?
s1 := "ctf"
s2 := ([]byte)(s1)
s2[0] = 'C'