在Go中将数组转换为切片

Fur*_*rge 55 go

这似乎是这将是整个interwebs一个相当普遍的事情,丰富的实例,但我似乎无法找到如何将一个转换的例子[32]byte[]byte.

我有一个函数,我从一个返回数组的外部库调用

func Foo() [32]byte {...}
Run Code Online (Sandbox Code Playgroud)

然后我需要将该结果传递给不同的函数以进行进一步处理.

func Bar(b []byte) { ... }
Run Code Online (Sandbox Code Playgroud)

不幸的是,如果我试着打电话

d := Foo()
Bar(d)
Run Code Online (Sandbox Code Playgroud)

我明白了

cannot convert d (type [32]byte) to type []byte
Run Code Online (Sandbox Code Playgroud)

[]byte(d)
Run Code Online (Sandbox Code Playgroud)

并没有好多少.我该怎么做,尤其是在没有创建数据副本的情况下(当我正在做的所有内容传递时,复制这些数据似乎很愚蠢).

Not*_*fer 82

这应该工作:

func Foo() [32]byte {
    return [32]byte{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}
}

func Bar(b []byte) {
    fmt.Println(string(b))
}

func main() {
    x := Foo()
    Bar(x[:])
}
Run Code Online (Sandbox Code Playgroud)

它不会创建底层缓冲区的副本

  • 哦,好吧,为什么这些事情总是必须如此合乎逻辑。 (4认同)
  • @BluBb_mADe 没有。切片基本上是 [covers](https://blog.golang.org/slices) 下的一个结构体,其底层引用为:缓冲区;它的长度;及其容量。要初始化切片的缓冲区 - 需要来自 _heap_ 而不是 _stack_(存储返回值的位置)的可寻址内存 - 因为堆栈内存在其功能之外不是持久的。这与人们不能做类似 [this](https://play.golang.org/p/edY6tPPlqeM) 的原因是一样的。 (3认同)
  • 是否有可能让像“Bar(Foo()[:])”这样的单行轮工作? (2认同)

jam*_*her 36

arr[:]  // arr is an array; arr[:] is the slice of all elements
Run Code Online (Sandbox Code Playgroud)


小智 7

这样就可以了:

slice := array[0:len(array)]
Run Code Online (Sandbox Code Playgroud)

还避免复制底层缓冲区.

  • 考虑到解决方案的有效性,我发现downvotes的数量有点苛刻...... (10认同)
  • 下限的默认值为0.上限的默认值为"len(x)",因此`x [0:len(x)]`更好地写为`x [:]`.这正是现有答案所说的. (5认同)
  • 尽管OP只想对底层数组进行完全转换,但了解指定下限和上限与切片注释相同是很有用的。例如,您可能想要分配一个数组(而不是使用 make slice),然后使用下限/上限表示法设置数组的部分。示例:https://play.golang.org/p/BwIvavioBj (2认同)

Ism*_*l H 5

您通常可以按其边界对数组进行切片:

var a [32]byte 
slice := a[:]
Run Code Online (Sandbox Code Playgroud)

更一般地,对于以下数组:

var my_array [LENGTH]TYPE
Run Code Online (Sandbox Code Playgroud)

您可以通过编写来生成不同大小的切片:

my_array[START_SLICE:END_SLICE]
Run Code Online (Sandbox Code Playgroud)

省略START_SLICE是否等于下限,END_SLICE如果等于上限,在您的情况下:

a[0:32] 
Run Code Online (Sandbox Code Playgroud)

生成底​​层数组的切片,等效于:

a[0:]
a[:32]
a[:]
Run Code Online (Sandbox Code Playgroud)