【问题标题】:Why can not convert [Size]byte to string in Go?为什么不能在 Go 中将 [Size]byte 转换为字符串?
【发布时间】:2015-03-18 10:02:57
【问题描述】:

我在执行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)

【问题讨论】:

    标签: arrays string go type-conversion slice


    【解决方案1】:

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

    引用Go Language Specification: Conversions:

    在以下任何一种情况下,非常量值 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
    }
    

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

    注意:

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

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

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

    【讨论】:

      猜你喜欢
      • 2014-11-22
      • 1970-01-01
      • 2021-04-11
      • 1970-01-01
      • 2017-11-11
      • 1970-01-01
      • 1970-01-01
      • 2016-06-30
      • 2021-07-28
      相关资源
      最近更新 更多