在Golang中创建数组字面量的数组

33

如何使用切片字面量在 Golang 中创建 int 数组的数组?

我尝试过:

test := [][]int{[1,2,3],[1,2,3]}

type Test struct {
   foo [][]int
}

bar := Test{foo: [[1,2,3], [1,2,3]]}

5
值得重申的是,您正在尝试创建一个切片而不是数组。要创建一个数组,您可以使用[N]type{42, 33, 567}[...]type{42, 33, 567}——它会从初始化器中的成员数量推断出大小。 - kostix
当然,我想在Go语言中你很少使用数组,并且语法非常相似,所以即使它们是不同的东西,我基本上可以互换两者。 - praks5432
我不会说我很少使用它们。在解析某些网络协议的代码中,通常会声明一个数组,然后多次重新切片它--将这些切片作为窗口传递给其他函数,以便访问底层数组。无论哪种情况,a) 我认为你可能对需要修正的模型有误解;-) b) 最好不要混淆那些稍后会遇到你帖子的读者。 - kostix
4个回答

51

你几乎做对了,但是内部数组的语法有些错误,需要像这样使用大括号:test := [][]int{[]int{1,2,3},[]int{1,2,3}} 或者稍微简洁一点的版本: test := [][]int{{1,2,3},{1,2,3}}

这个表达式被称为“复合字面量”,你可以在这里阅读更多相关信息:https://golang.org/ref/spec#Composite_literals

但作为一个基本的经验法则,如果你有嵌套结构,你就必须递归地使用这种语法,它非常冗长。


2
您不必在内部数组中使用相同的语法:http://play.golang.org/p/Wdhabb3qca - twotwotwo
@twotwotwo 是的,从技术上讲这是不同的,而且在我看来更可取。 - evanmcdonnal
3
感谢您增加了较短的示例,但答案仍然说“您必须递归使用语法。这非常冗长。”和“您必须对内部数组使用相同的语法”,当考虑到内部切片可以用不同且更短的方式编写时,这些说法似乎会让人感到困惑或不准确。 - twotwotwo
@twotwotwo 好的,我已经改了措辞。我认为这是挑剔。它们具有相同的语法,都被称为“复合字面量”,只是在内部集合的情况下,类型信息可以被推断出来,但使用 []{} 真正重要的区别。 - evanmcdonnal

6

只需用花括号替换方括号。在Go语言中,数组字面量使用花括号标识。

test := [][]int{{1,2,3},{1,2,3}}


6
在其他一些编程语言中,如Perl、Python和JavaScript,[1,2,3]可能是数组文字(array literal),但在Go语言中,复合字面量使用大括号,并且需要指定外层切片的类型:
package main

import "fmt"

type T struct{ foo [][]int }

func main() {
    a := [][]int{{1, 2, 3}, {4, 5, 6}}
    b := T{foo: [][]int{{1, 2, 3}, {4, 5, 6}}}
    fmt.Println(a, b)
}

您可以在Playground上运行或玩耍此内容
Go编译器足够巧妙,可以确定 [][]int 的元素是 [] int ,而不需要您在每个元素上都这样说。 但是,您必须写出外部类型的名称。

1
一个切片字面量的写法是[]type{<value 1>, <value 2>, ... }。一个int类型的切片可以这样定义:[]int{1,2,3},而一个int类型的切片的切片则可以这样定义:[][]int{[]int{1,2,3},[]int{4,5,6}}
groups := [][]int{[]int{1,2,3},[]int{4,5,6}}

for _, group := range groups {
    sum := 0
    for _, num := range group {
        sum += num
    }
    fmt.Printf("The array %+v has a sum of %d\n", sub, sum)
} 

3
无需指定值的类型:https://play.golang.org/p/Wdhabb3qca - twotwotwo

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