【问题标题】:Using spread when initializing array in Go在 Go 中初始化数组时使用扩展
【发布时间】:2019-09-24 03:21:35
【问题描述】:

我有一个重复的值列表,我想在初始化多个这样的数组时重复使用:

package main

import (
    "fmt"
)

func main() {
    var i = []int{1, 2, 3}
    var a = []int{2, i..., 3}
    fmt.Println(a)
}

上面的代码给出了以下错误:

./prog.go:9:20: 语法错误:意外 ...,需要逗号或 }

我想使用扩展 ... 运算符,但这在初始化数组时似乎是不可能的。

是我遗漏了什么还是不允许传播?

【问题讨论】:

    标签: arrays go slice


    【解决方案1】:

    在将切片传递给可变参数函数时,您只能将 ... 与切片一起使用。见Spec: Passing arguments to ... parameters

    因此,例如,您可以在将其传递给 append() 时使用它:

    var i = []int{1, 2, 3}
    a := append([]int{2}, i...)
    a = append(a, 3)
    fmt.Println(a)
    

    哪些输出(在Go Playground 上试试):

    [2 1 2 3 3]
    

    或者上面可以写成一行:

    a := append(append([]int{2}, i...), 3)
    

    请注意,这可能很紧凑,但不一定高效,因为它可能会在后台创建和复制多个支持数组。

    为确保单一分配,您可以使用make() 并提供容量,例如:

    a := make([]int, 0, 2+len(i))
    a = append(a, 2)
    a = append(a, i...)
    a = append(a, 3)
    

    Go Playground 上试试这个。

    另一个解决方案是使用copy(),如果您预先分配了切片(使用make() 或在复合文字中使用索引):

    a := []int{2, 4: 3}
    copy(a[1:], i)
    

    Go Playground 上试试这个。这里的缺点是索引 (4: 3) 必须是常数,不能像1 + len(i) 这样。如果您想预先分配切片(例如make([]int, 2+len(i))),则不能将其与复合文字结合起来列出元素。

    【讨论】:

    • 非常感谢。我希望它有点冗长,但会完成工作。
    • @AquilaX 添加了关于效率和一些替代解决方案的说明。
    猜你喜欢
    • 1970-01-01
    • 2020-08-18
    • 2012-11-13
    • 2016-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-23
    • 1970-01-01
    相关资源
    最近更新 更多