NOTE
1.6 string
1. 字符集 计算机只能存储字节(二进制),因此字符肯定也是用字节存储的 但是存储后怎么显示呢?需要建立字节和字符的映射,这就是字符集 比如 - 1.1. Unicode字符集 - 由来 最开始只有ASCII字符集,只支持英文; 为了支持中文简体,推出GB2312; 为了支持中文繁体,推出BIG5.
这是历史学习笔记,可能存在过时或不完整的理解。
1. 字符集
计算机只能存储字节(二进制),因此字符肯定也是用字节存储的 但是存储后怎么显示呢?需要建立字节和字符的映射,这就是字符集 比如
1.1. Unicode字符集
- 由来 最开始只有ASCII字符集,只支持英文; 为了支持中文简体,推出GB2312; 为了支持中文繁体,推出BIG5… 太多了,没有统一,于是Unicode出来了
- 定长编码
- 变长编码
- UTF-8字符集

2. 是什么
- 采用Unicode编码的字符串
3. 使用
3.1. 基本使用
func TestString1(t *testing.T) {
s := "hello world"
fmt.Println(s, len(s))
s1 := s + "!"
fmt.Println(s1, len(s1))
s2 := s[:5]
fmt.Println(s2, len(s2))
for _, i := range s2 {
fmt.Println(i, string(i))
}
}
//输出
hello world 11
hello world! 12
hello 5
104 h
101 e
108 l
108 l
111 o
3.2. string和[]byte之间的转换
- string转[]byte
func str2bytes(s string) []byte {
p := make([]byte, len(s))
for i := 0; i < len(s); i++ {
c := s[i]
p[i] = c
}
return p
}
func TestString2(t *testing.T) {
fmt.Println(str2bytes("hello"))
}
//输出
[104 101 108 108 111]
- []byte转string
func TestString3(t *testing.T) {
fmt.Println(bytes2str([]byte{104, 101, 108, 108, 111}))
}
func bytes2str(s []byte) (p string) {
data := make([]byte, len(s))
for i, c := range s {
data[i] = c
}
hdr := (*reflect.StringHeader)(unsafe.Pointer(&p))
hdr.Data = uintptr(unsafe.Pointer(&data[0]))
hdr.Len = len(s)
return p
}
//输出
hello
4. 原理
4.1. 数据结构
type StringHeader struct {
Data uintptr//字符串指向的底层字节数组
Len int//字符串的字节的长度
}
4.1.1. 如何确定字符结尾
- C语言采用的是
'\0'确定字符边界,而Golang则是采用长度字段
4.1.2. 底层是字节数组,不可变
s := "test"
fmt.Println(s[1])
s[1] = 'c'//编译不能通过

4.1.2.1. 为什么不可变
s := "test"
s1 := s[1:]
- 如果s1能改,那么会影响到s,这样可能会造成不可预估的后果

