为了账号安全,请及时绑定邮箱和手机立即绑定

为什么不能在 Go 中将 [Size]byte 转换为字符串?

为什么不能在 Go 中将 [Size]byte 转换为字符串?

Go
潇湘沐 2021-09-13 09:49:20
我有一个大小的字节数组,我在做md5.Sum().data := []byte("testing")var pass string var b [16]byteb = md5.Sum(data)pass = string(b)错误:cannot convert b (type [16]byte) to type string我找到了这个问题的解决方案改成:pass = string(b[:])但是为什么不能这样使用呢?pass = string(b)
查看完整描述

1 回答

?
HUWWW

TA贡献1874条经验 获得超12个赞

简短的回答是因为 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

}

如果您决定使用数组作为输入,由于长度是类型的一部分,您将限制函数的可用性,它只能采用相同长度的数组:


func sum2(s [2]int) (sum int) {

    for _, v := range s {

        sum += v

    }

    return

}

你可以调用sum2()类型的值仅[2]int但如果你有类型的数组[3]int,你不能因为这些2种类型是不同的!sum2()如果您只有一个int's切片,您也无法调用(您无法访问切片的后备数组)。同时,您可以sum()使用所有[]int切片调用您的函数,如果您有一个数组,您仍然可以通过传递arr[:]给您的sum()函数来使用它。


笔记:


另请注意,将“随机”字节切片转换为 astring很可能不是您想要的,因为“随机”字节切片可能不是有效的 UTF-8 字节序列。


而是使用encoding/hex包将结果转换为十六进制字符串,如下所示:


fmt.Println(hex.EncodeToString(b[:]))


查看完整回答
反对 回复 2021-09-13
  • 1 回答
  • 0 关注
  • 187 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信