在Go中将数组转换为切片


73

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

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

func Foo() [32]byte {...}

然后,我需要将该结果传递给其他函数以进行进一步处理。

func Bar(b []byte) { ... }

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

d := Foo()
Bar(d)

我懂了

cannot convert d (type [32]byte) to type []byte

在做

[]byte(d)

好多了。我该怎么做,尤其是不创建数据副本(当我正在做的事情是传递数据时,似乎很愚蠢地复制此数据)。


Answers:


110

这应该工作:

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[:])
}

而且它不会创建基础缓冲区的副本


2
是否有可能获得像Bar(Foo()[:])工作一样的内衬?
BluBb_mADe

2
@BluBb_mADe号 切片本质上是一个底层的结构,具有对以下内容的潜在引用:它的长度;及其容量。要初始化片的缓冲区,需要从而不是从堆栈访问可寻址的内存(在堆栈中存储返回值),这是因为堆栈内存在其功能之外并不持久。这是同样的原因,我们不能这样做了这个
colm.anseo,

3
哦,为什么这些事情总是必须如此合乎逻辑。
BluBb_mADe


10

这将达到目的:

slice := array[0:len(array)]

还避免复制基础缓冲区。


5
下限的默认值为0。上限的默认值为,len(x)因此x[0:len(x)]最好编写为x[:]。这正是现有答案所说的。
Dave C

12
考虑到该解决方案的有效性,我发现反对投票的人数有些苛刻……
Mike Gleason jr Couturier

1
尽管OP只是希望对基础数组进行完全转换,但了解指定下限和上限与切片注释相同是很有用的。例如,您可能想分配一个数组(而不是使用make slice),然后使用下限/上限符号设置数组的各个部分。例如:play.golang.org/p/BwIvavioBj
比尔·卡兹

4

通常,您可以使用:

var a [32]byte 
slice := a[:]

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

var my_array [LENGTH]TYPE

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

my_array[START_SLICE:END_SLICE]

在您的情况下,START_SLICE如果它等于下限,END_SLICE或者等于上限,则省略:

a[0:32] 

产生基础数组的切片,等效于:

a[0:]
a[:32]
a[:]
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.