soa*_*bar 10 arrays string type-conversion go slice
我有一个大小的字节数组,我做了之后md5.Sum().
data := []byte("testing")
var pass string
var b [16]byte
b = md5.Sum(data)
pass = string(b)
Run Code Online (Sandbox Code Playgroud)
错误:
cannot convert b (type [16]byte) to type string
Run Code Online (Sandbox Code Playgroud)
我找到了解决这个问题的方法
改成:
pass = string(b[:])
Run Code Online (Sandbox Code Playgroud)
但为什么不能这样使用呢?
pass = string(b)
Run Code Online (Sandbox Code Playgroud)
icz*_*cza 20
简短的回答是因为Go语言规范不允许它.
引用Go语言规范:转换:
在任何这些情况下,非常量值
x都可以转换为类型T:
x可分配给T.x的类型和T底层类型相同.x的类型和T是未命名的指针类型,它们的指针基类型具有相同的基础类型.- x的类型,
T是整数或浮点类型.- x的类型,
T都是复杂的类型.x是一个整数或一个字节或符文切片,T是一个字符串类型.x是一个字符串,T是一个字节或符文的片段.
规范仅允许将一片字节或符文转换为字节string数组,而不是字节数组.
答案很长
在Go数组和切片是不同的类型.数组的大小是类型的一部分.
切片比数组更通用,并且将数组转换为表示相同系列值的切片非常容易:( arr[:]并且也很便宜,结果切片将共享数组作为其后备数组,不会重新分配或复制完成).
因此,所有功能和支持都是为切片而不是为数组提供的.
只是图像你想创建一个简单的函数,它接受一个切片(任意长度)的int数字,并返回数字的总和.像这样的东西:
func sum(s []int) (sum int) {
for _, v := range s {
sum += v
}
return
}
Run Code Online (Sandbox Code Playgroud)
如果您决定使用数组作为输入,因为长度是类型的一部分,您将限制函数的可用性,它只能采用相同长度的数组:
func sum2(s [2]int) (sum int) {
for _, v := range s {
sum += v
}
return
}
Run Code Online (Sandbox Code Playgroud)
您sum2()只能使用类型的值调用,[2]int但如果您有类型的数组[3]int,则不能,因为这两种类型是不同的!sum2()如果你只有一片int(你无法访问切片的支持数组),你也无法调用.同时你可以sum()用所有[]int切片调用你的函数,如果你有一个数组,你仍然可以通过传递arr[:]给你的sum()函数来使用它.
注意:
另请注意,将"随机"字节切换为a string很可能不是您想要的,因为"随机"字节切片可能不是有效的UTF-8字节序列.
而是使用encoding/hex包将结果转换为十六进制字符串,如下所示:
fmt.Println(hex.EncodeToString(b[:]))
Run Code Online (Sandbox Code Playgroud)