在Go语言中将数组转换为切片

116

这似乎是一个非常普遍的问题,在互联网上有很多例子,但我似乎找不到如何将 [32]byte 转换为 []byte 的示例。

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

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

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

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

不幸的是,如果我尝试调用

d := Foo()
Bar(d)

我得到

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

处理中

[]byte(d)

这种方式并不好。我该如何做到这一点,特别是在不创建数据副本的情况下(当我只是传递它时复制这些数据似乎很愚蠢)。


4
请查看 https://blog.golang.org/slices - Dave C
5个回答

145

这应该可以运行:

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

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


5
能否让像 Bar(Foo()[:]) 这样的一行代码工作? - Ramon
5
@BluBb_mADe 不行。一个 slice 基本上是一个结构体(struct),它的底层引用包括:缓存区、它的长度和它的容量。要初始化一个 slice 的缓存区,需要来自 而不是 的可寻址内存(返回值所存储的地方)。这是因为栈内存在其函数外部不是持久性的。这也是为什么不能像 这样 这样做的原因。 - colm.anseo
5
哦,好吧,为什么这些事情总是那么合乎逻辑呢。 - Ramon

104
arr[:]  // arr is an array; arr[:] is the slice of all elements

13

这样就可以了:

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

此外,还避免了复制底层缓冲区。


11
下限的默认值为0,上限的默认值为len(x),因此x[0:len(x)]最好写成x[:]。这正是现有答案所说的。 - Dave C
14
考虑到解决方案的有效性,我认为给予这么多的踩有点过分了。 - Mike Gleason jr Couturier
1
尽管 OP 只是想要对底层数组进行完全转换,但知道指定下限和上限与切片注释相同是有用的。例如,您可能希望分配一个数组(而不是使用 make 切片),然后使用下限/上限符号设置数组的部分。示例:https://play.golang.org/p/BwIvavioBj - Bill Katz

10
你可以使用 : 来按照边界切割一个数组:
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[:]

-1
说,如果你有一个已经存在的数组my_array,请创建一个新的切片并将数组附加到它上面。
var s []string
s = append(s, my_array...)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接