在将字节切片转换为字符串时,Golang会进行任何转换吗?

lau*_*ent 3 string byte casting go slice

在将字节切片转换为字符串时,Golang会进行任何转换或以某种方式尝试解释字节吗?我刚试过一个包含空字节的字节片,看起来它仍然保持字符串不变.

var test []byte
test = append(test, 'a')
test = append(test, 'b')
test = append(test, 0)
test = append(test, 'd')
fmt.Println(test[2] == 0) // OK
Run Code Online (Sandbox Code Playgroud)

但是如何使用无效的unicode点或UTF-8编码.铸造能否失败或数据被破坏?

pet*_*rSO 9

Go编程语言规范

字符串类型

字符串类型表示字符串值的集合.字符串值是(可能为空)字节序列.

转换

转换为字符串类型的转换

将一片字节转换为字符串类型会产生一个字符串,其连续字节是片的元素.

string([]byte{'h', 'e', 'l', 'l', '\xc3', '\xb8'})   // "hellø"
string([]byte{})                                     // ""
string([]byte(nil))                                  // ""

type MyBytes []byte
string(MyBytes{'h', 'e', 'l', 'l', '\xc3', '\xb8'})  // "hellø"
Run Code Online (Sandbox Code Playgroud)

将字符串类型的值转换为字节切片类型会生成一个切片,其连续元素是字符串的字节.

[]byte("hellø")   // []byte{'h', 'e', 'l', 'l', '\xc3', '\xb8'}
[]byte("")        // []byte{}

MyBytes("hellø")  // []byte{'h', 'e', 'l', 'l', '\xc3', '\xb8'}
Run Code Online (Sandbox Code Playgroud)

字符串值是(可能为空)字节序列.字符串值可能表示也可能不表示以UTF-8编码的Unicode字符.有一个从转换时,没有字节的解释byte切片string也没有从stringbyte切片.因此,不会更改字节,转换也不会失败.


jos*_*hlf 5

不,演员不能失败。这是一个显示此内容的示例(在 Go Playground 中运行):

b := []byte{0x80}
s := string(b)
fmt.Println(s)
fmt.Println([]byte(s))
for _, c := range s {
    fmt.Println(c)
}
Run Code Online (Sandbox Code Playgroud)

这打印:

?
[128]
65533
Run Code Online (Sandbox Code Playgroud)

请注意,根据Go 规范,对无效的 UTF-8 范围进行了很好的定义:

对于字符串值,“范围”子句从字节索引 0 开始迭代字符串中的 Unicode 代码点。在连续迭代中,索引值将是连续 UTF-8 编码代码点的第一个字节的索引字符串和第二个符文类型的值将是相应代码点的值。如果迭代遇到无效的 UTF-8 序列,则第二个值将是 0xFFFD,即 Unicode 替换字符,下一次迭代将在字符串中前进一个字节。