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

时间:2015-01-20 08:42:09

标签: arrays string go type-conversion slice

我在执行md5.Sum()之后得到了一个大小的字节数组。

data := []byte("testing")
var pass string 
var b [16]byte
b = md5.Sum(data)
pass = string(b)

错误:

cannot convert b (type [16]byte) to type string

我在此problem

找到解决方案

更改为:

pass = string(b[:])

但为什么不能这样使用呢?

pass = string(b)

1 个答案:

答案 0 :(得分:20)

简短回答是因为Go语言规范不允许这样做。

引用Go Language Specification: Conversions

  

在任何这些情况下,非常数值x都可以转换为T类型:

     
      
  • x可分配给T
  •   
  • x'类型和T具有相同的基础类型。
  •   
  • x'类型和T是未命名的指针类型,它们的指针基类型具有相同的基础类型。
  •   
  • x&type; T是整数或浮点类型。
  •   
  • x&type; 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。同时,您可以使用所有sum()切片调用[]int函数,如果您有数组,则仍可以将arr[:]传递给sum()函数来使用它。

注意:

另请注意,转换"随机"到string的字节切片很可能不是你想要的,因为"随机"字节片可能不是有效的UTF-8字节序列。

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

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