在 Go 中,字符串(string
)是一种不可变的数据类型,用于表示文本数据。以下是关于 Go 中字符串的一些重要特性和底层实现:
1. 不可变性:
Go 中的字符串是不可变的,这意味着一旦创建,字符串的内容不能被修改。对字符串的操作通常会返回一个新的字符串,而不是修改原始字符串的值。
2. UTF-8 编码:
字符串在 Go 中是按照 UTF-8 编码的。UTF-8 是一种变长字符编码,可以表示 Unicode 字符集中的所有字符。字符串的底层字节数组存储的是 UTF-8 编码的字节序列。
3. 字符串的表示方式:
Go 中的字符串可以用双引号或反引号表示。使用双引号表示的字符串可以包含转义字符,而使用反引号表示的字符串是原始字符串,不会进行转义。
str1 := "Hello, Go!" // 使用双引号表示的字符串
str2 := `This is a raw string
with multiple lines.` // 使用反引号表示的原始字符串
4. reflect.StringHeader 结构体:
Go 中的字符串底层实现使用了 reflect.StringHeader
结构体。这个结构体定义如下:
type StringHeader struct {
Data uintptr
Len int
}
Data
字段是一个指向底层字节数组的指针(uintptr
类型),这个数组存储了字符串的实际数据。Len
字段表示字符串的长度,即字符的个数。
Go版本为1.21.5,该结构在之后的版本中可能会被删除
5. 字符串的创建和使用:
str := "Hello, Go!"
在上述代码中,字符串 “Hello, Go!” 会被存储在内存中,同时 reflect.StringHeader
结构体的 Data
字段会指向这个字符串的底层字节数组的起始地址。
字符串的切片操作,例如 str[1:5]
,会返回一个新的字符串,但底层共享相同的字节数组。这也符合字符串的不可变性特性。
6. 字符串的转换:
Go 中字符串与字节切片之间可以相互转换,但需要注意的是字符串是不可变的,转换时会创建一个新的字符串。
str := "Hello, Go!"
bytes := []byte(str) // 将字符串转换为字节切片
str2 := string(bytes) // 将字节切片转换为字符串
7. 扩展:UTF-8 简介
UTF-8(8位元,Universal Character Set/Unicode Transformation Format)是一种针对Unicode的可变长度字符编码。它可以用来表示Unicode标准中的任何字符,而且其编码中的第一个字节仍与ASCII相容,使得原来处理ASCII字符的软件无须或只进行少部分修改后,便可继续使用。因此,它逐渐成为电子邮件、网页及其他存储或传送文字的应用中,优先采用的编码。
UTF-8编码的规则如下:
- ASCII字符:ASCII字符在UTF-8编码中保持不变。即,ASCII字符的UTF-8编码与其ASCII码值相同。
- 非ASCII字符:非ASCII字符在UTF-8编码中由多个字节表示。其中,第一个字节的最高位为1,其他字节的最高位为10或11。具体来说,一个字符的UTF-8编码由以下几部分组成:
- 字节序标记(Byte Order Mark,BOM):BOM是一个特殊的字符,用于标识文本流的字节顺序。在UTF-8编码中,BOM由三个连续的字节组成:EF BB BF。
- 字符编码:每个字符的UTF-8编码由一个或多个字节组成。对于非ASCII字符,第一个字节的最高位为1,而其他字节的最高位为10或11。根据字符的Unicode码点(code point),第一个字节的次高位可以是0到2。其他字节的次高位可以是0到6。
- 长度指示:对于多字节字符,UTF-8编码中的前缀部分包含一个字节,用于指示后续字节的数量。长度指示由特定的二进制模式表示。
- 具体字符的编码:根据Unicode码点,每个字符的UTF-8编码由特定的字节序列表示。
UTF-8编码具有以下优点:
- 与ASCII兼容:UTF-8编码使得ASCII字符保持不变,因此与ASCII编码兼容。这使得原来处理ASCII字符的软件可以无须修改或只需进行少部分修改后,便可处理UTF-8编码的文本。
- 可变长度:UTF-8编码是可变长度的,这意味着每个字符的编码长度可以是1到4个字节。这使得UTF-8编码具有较高的灵活性,可以表示各种语言和符号。
- 广泛支持:UTF-8编码已成为互联网上的标准编码之一。许多软件、操作系统和应用程序都支持UTF-8编码,使其成为跨平台和国际化的理想选择。
- 广泛应用:由于UTF-8编码的广泛支持和使用,它在电子邮件、网页、社交媒体、电子商务网站等各个领域得到广泛应用。
汉字在UTF-8编码中占3个字节,也就是24位。
声明:本作品采用署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)进行许可,使用时请注明出处。
Author: mengbin
blog: mengbin
Github: mengbin92
cnblogs: 恋水无意
腾讯云开发者社区:孟斯特