简体   繁体   English

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

[英]Why can not convert [Size]byte to string in Go?

I have a sized byte array that I got after doing md5.Sum() . 我有一个大小的字节数组,我做了md5.Sum()后得到的。

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

The error: 错误:

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

I find the solution at this problem 我找到了解决这个问题的方法

Change to: 改成:

pass = string(b[:])

But why can not use it like this? 但为什么不能这样使用呢?

pass = string(b)

Short answer is because the Go Language Specification does not permit it. 简短的回答是因为Go语言规范不允许它。

Quoting from the Go Language Specification: Conversions : 引用Go语言规范:转换

A non-constant value x can be converted to type T in any of these cases: 在任何这些情况下,非常数值x都可以转换为类型T

  • x is assignable to T . x可分配给T
  • x 's type and T have identical underlying types. x的类型和T具有相同的底层类型。
  • x 's type and T are unnamed pointer types and their pointer base types have identical underlying types. x的类型和T是未命名的指针类型,它们的指针基类型具有相同的基础类型。
  • x's type and T are both integer or floating point types. x的类型和T都是整数或浮点类型。
  • x's type and T are both complex types. x的类型和T都是复杂类型。
  • x is an integer or a slice of bytes or runes and T is a string type. x是整数或字节或符文切片, T是字符串类型。
  • x is a string and T is a slice of bytes or runes. x是一个字符串, T是一个字节或符文的片段。

The specification only allows converting a slice of bytes or runes to string , but not an array of bytes. 规范仅允许将一片字节或符文转换为string ,而不是字节数组。

Long answer 答案很长

In Go arrays and slices are distinct types. 在Go数组和切片是不同的类型。 The size of an array is part of the type. 数组的大小是类型的一部分。

Slices are much more general than arrays, and converting an array to a slice which represents the same series of values is very easy: arr[:] (and is also cheap, the result slice will share the array as its backing array, no reallocation or copying will be done). 切片比数组更通用,并且将数组转换为表示相同系列值的切片非常容易: arr[:] (并且也很便宜,结果切片将共享数组作为其后备数组,无需重新分配或复制将完成)。

Because of this, all functions and support are provided for slices and not for arrays. 因此,所有功能和支持都是为切片而不是为数组提供的。

Just image you want to create a simple function which takes a slice (with any length) of int numbers and returns the sum of the numbers. 只是想要创建一个简单函数的图像,它接受一个切片(任意长度)的int数字并返回数字的总和。 Something like this: 像这样的东西:

func sum(s []int) (sum int) {
    for _, v := range s {
        sum += v
    }
    return
}

If you would decide to use an array as the input, since the length is part of the type, you would limit the usability of your function, it could only take arrays of the same length: 如果您决定使用数组作为输入,因为长度是类型的一部分,您将限制函数的可用性,它只能采用相同长度的数组:

func sum2(s [2]int) (sum int) {
    for _, v := range s {
        sum += v
    }
    return
}

You can call sum2() only with values of type [2]int but if you have an array of type [3]int , you can't because those 2 types are distinct! 你只能使用类型为[2]int值调用sum2() ,但是如果你有一个类型为[3]int的数组, 则不能,因为这两种类型是不同的! You also cannot call sum2() if you only have a slice of int 's (you can't access the backing array of a slice). 如果你只有一个int片段(你不能访问片段的后备数组),你也不能调用sum2() )。 Meanwhile you can call your sum() function with all []int slices, and if you have an array, you can still use it by passing arr[:] to your sum() function. 同时你可以用all []int切片调用你的sum()函数,如果你有一个数组,你仍然可以通过将arr[:]传递给你的sum()函数来使用它。

Note: 注意:

Also note that converting a "random" slice of bytes to a string is most likely not what you want because a "random" slice of bytes may not be a valid UTF-8 byte sequence. 另请注意,将“随机”字节切换为string很可能不是您想要的,因为“随机”字节切片可能不是有效的UTF-8字节序列。

Instead use the encoding/hex package to convert the result to a hex string like this: 而是使用encoding/hex包将结果转换为十六进制字符串,如下所示:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM