为什么不能在Go中将[Size]字节转换为字符串? [英] Why can not convert [Size]byte to string in Go?

查看:306
本文介绍了为什么不能在Go中将[Size]字节转换为字符串?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

错误:

 无法将b(类型[16]字节)转换为字符串



'p>我发现在这个溶液

更改为:

  pass = string(b [:])

但是为什么不能像这样使用它?

  

引用 href =http://golang.org/ref/spec#Conversions =noreferrer> Go Language Spe cification:Conversions


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


  • x 可分配给 T

  • x 的类型和 T 具有相同的基础类型

  • x 的类型和 T 是未命名的指针类型,它们的指针基类型具有相同的基础类型。 $ c> T 都是整型或浮点型。
  • x的类型和 T 都是复数类型。

  • x 是一个整数或一个字节或符文片段, T 是一个字符串类型。
  • 是一个字符串, T 是一段字节或符文。

将一段字节或符文转换为 string ,但不是字节数组。



长答案

在Go中,数组和切片是不同的类型。数组的大小是类型的一部分。



切片比数组更加通用,将数组转换为代表相同数值的切片非常简单: arr [:] (并且价格便宜,结果片将共享阵列作为其后备阵列,不会进行重新分配或复制)。



因此,所有函数和支持都是为切片而不是为数组提供的。



只需要您想要创建的图像简单的函数,它接受 int 数字的切片(任意长度)并返回数字的总和。就像这样:

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

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



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

您只能使用 [2] int 类型的值调用 sum2(),但是如果您有一个<$ code> [3] int ,你不能,因为这两种类型是不同的!如果你只有一部分 int 的话,你也不能调用 sum2()片的后备阵列)。同时你可以用所有的 [] int 切片调用你的 sum()函数,如果你有一个数组,你仍然可以通过向 sum()函数传递 arr [:] 来使用它。



注意:

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



请使用 编码/十六进制 包将结果转换为如下所示的十六进制字符串:

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


I have a sized byte array that I got after doing 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.

Quoting from the 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.

The specification only allows converting a slice of bytes or runes to string, but not an array of bytes.

Long answer

In Go arrays and slices are distinct types. 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).

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. 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! You also cannot call sum2() if you only have a slice of int's (you can't access the backing array of a slice). 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.

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.

Instead use the encoding/hex package to convert the result to a hex string like this:

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

这篇关于为什么不能在Go中将[Size]字节转换为字符串?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆