[]byte(string)与[]byte(*string)的区别

6
我很好奇为什么Go语言没有提供一个[]byte(*string)方法。从性能的角度来看,[]byte(string)会复制输入参数并增加更多的成本(虽然这似乎很奇怪,因为字符串是不可变的,为什么要复制它们呢)?

https://dev59.com/k2Yq5IYBdhLWcg3wkRe_ - stackoverflower
2个回答

26

[]byte("something") 不是一个函数(或方法)调用,它是一种类型转换

类型转换“本身”不会复制值。但是将 string 转换为 []byte 会复制值,因为结果的字节数组是可变的,如果不进行复制,则可以修改/更改 string 值(string 的内容)而这是不可变的,必须按照 规范:字符串类型 中所述:

字符串是不可变的:创建后,无法更改字符串的内容。

请注意,当证明不可变的 string 不能/不会被修改时,有几种情况下 string <=> []byte 转换不会进行复制,因为编译器会对其进行优化。这些情况很少且“硬编码”。

这样的例子是从一个键类型为string的映射中查找一个值,你可以使用一个[]byte索引该映射,并将其转换为string(当然要看源代码)。
key := []byte("some key")

var m map[string]T
// ...
v, ok := m[string(key)]  // Copying key here is optimized away

另一个优化是在遍历显式转换为字节切片的 string 的字节时进行的:
s := "something"
for i, v := range []byte(s) { // Copying s is optimized away
    // ...
}

(请注意,如果没有进行转换,for range 将会遍历字符串的 rune 而不是其 UTF8 编码的字节。)

谢谢您的快速回复。我忘记了字节切片是可变的这一事实,所以需要进行复制。谢谢。 - stackoverflower
2
请注意,有一个不可变字节数组的功能请求 https://github.com/golang/go/issues/2205 - stackoverflower

5
我很好奇为什么Golang不提供[]byte(*string)方法。
因为这没有意义。
指针(任何类型的)不能以任何有意义的方式表示为[]byte。
从性能的角度来看,[]byte(string)会复制输入参数并增加更多的成本(尽管这似乎很奇怪,因为字符串是不可变的,为什么要复制它们)?
从[]byte转换为string(反之亦然)确实涉及复制,因为字符串是不可变的,但字节数组不是。
然而,使用指针也无法解决这个问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接