为什么不能在 Go 中将 [Size]byte 转换为字符串?
Why can not convert [Size]byte to string in Go?
我有一个大小的字节数组,是我在 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)
简短的回答是因为 Go 语言规范不允许。
引自Go Language Specification: Conversions:
A non-constant value x
can be converted to type T
in any of these cases:
x
is assignable to T
.
x
's type and T
have identical underlying types.
x
's type and T
are unnamed pointer types and their pointer base types have identical underlying types.
- x's type and
T
are both integer or floating point types.
- x's type and
T
are both complex types.
x
is an integer or a slice of bytes or runes and T
is a string type.
x
is a string and T
is a slice of bytes or runes.
规范只允许将一段字节或符文转换为 string
,而不是字节数组。
长答案
在 Go 中,数组和切片是不同的类型。数组的大小是类型的一部分。
切片比数组更通用,将数组转换为表示相同系列值的切片非常容易:arr[:]
(而且也很便宜,结果切片将共享数组作为它的后备数组,不会进行重新分配或复制。
因此,所有函数和支持都是为切片而不是数组提供的。
只是想创建一个简单的函数,它接受 int
个数字的切片(任意长度)和 returns 个数字的总和。像这样:
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()
函数来使用它。
注:
另请注意,将 "random" 字节片转换为 string
很可能不是您想要的,因为 "random" 字节片可能不是有效的 UTF-8字节序列。
而是使用 encoding/hex
包将结果转换为十六进制字符串,如下所示:
fmt.Println(hex.EncodeToString(b[:]))
我有一个大小的字节数组,是我在 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)
简短的回答是因为 Go 语言规范不允许。
引自Go Language Specification: Conversions:
A non-constant value
x
can be converted to typeT
in any of these cases:
x
is assignable toT
.x
's type andT
have identical underlying types.x
's type andT
are unnamed pointer types and their pointer base types have identical underlying types.- x's type and
T
are both integer or floating point types.- x's type and
T
are both complex types.x
is an integer or a slice of bytes or runes andT
is a string type.x
is a string andT
is a slice of bytes or runes.
规范只允许将一段字节或符文转换为 string
,而不是字节数组。
长答案
在 Go 中,数组和切片是不同的类型。数组的大小是类型的一部分。
切片比数组更通用,将数组转换为表示相同系列值的切片非常容易:arr[:]
(而且也很便宜,结果切片将共享数组作为它的后备数组,不会进行重新分配或复制。
因此,所有函数和支持都是为切片而不是数组提供的。
只是想创建一个简单的函数,它接受 int
个数字的切片(任意长度)和 returns 个数字的总和。像这样:
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()
函数来使用它。
注:
另请注意,将 "random" 字节片转换为 string
很可能不是您想要的,因为 "random" 字节片可能不是有效的 UTF-8字节序列。
而是使用 encoding/hex
包将结果转换为十六进制字符串,如下所示:
fmt.Println(hex.EncodeToString(b[:]))