创建数组的数组的复合字面量

huangapple go评论88阅读模式
英文:

Creating composite literal of array of arrays

问题

我想在结构体中创建一个包含数组的数组的复合字面量。在结构体外部,这是可行的。

package main

import "fmt"

func main() {
    x := [...][]string{{"a", "b"}}

    fmt.Printf("%s", x)
}

可以正常工作(http://play.golang.org/p/C2RbNnd7LL)。

但是我无法在结构体中定义一个类型为 [...][]string 的字段。就像在 http://play.golang.org/p/wHNeeuAJuO 中一样。

package main

import "fmt"

type t struct {
    f    [...][]string
}

func main() {
    x := [...][]string{{"a", "b"}}
    y := t{x}
    fmt.Printf("%s", y)
}

f 给出了错误信息 "use of [...] array outside of array literal"。

英文:

I want to create a composite literal of arrays of arrays within a struct. Outside of a struct

package main

import "fmt"

func main() {
  x := [...][]string {{"a", "b"}}

  fmt.Printf("%s", x)
}

works. (http://play.golang.org/p/C2RbNnd7LL)

But I can't define a field of type [...][]string within a struct. As in http://play.golang.org/p/wHNeeuAJuO

package main

import "fmt"

type t struct {
    f    [...][]string
}

func main() {
  x := [...][]string {{"a", "b"}}
  y := t{x}
  fmt.Printf("%s", y)
}

f gives the errror use of [...] array outside of array literal

答案1

得分: 2

问题在于[...]elementType不是一个有效的类型名称。你可以使用初始化语法[...]int{1, 2, 3, 4},因为编译器可以看到有多少个元素来确定实际的类型(在这种情况下是[4]int)。

如果你想要一个类似数组的类型,但没有固定的编译时大小,可以使用切片:

type t struct {
    f    [][]string
}

或者,如果元素的数量在编译时是固定的,并且你仍然想使用数组,你需要在类型定义中指定实际的元素数量。

英文:

The problem is that [...]elementType is not a valid type name. You can use the syntax with the initialiser syntax like [...]int{1, 2, 3, 4} because the compiler can see how many elements there are to determine the actual type ([4]int in this case).

If you want an array-like type that doesn't have a fixed compile time size, use a slice:

type t struct {
    f    [][]string
}

Alternatively, if the number of elements is fixed at compile time and you still want to use an array, you will need to specify the actual element count in your type definition.

答案2

得分: 1

简短回答:

符号[...]可以用于构建数组字面量,但不能用于数组声明。在你提供的示例中,[...]符号用于声明结构体元素,因此出现了错误。将[...]替换为[n],其中n是数组的实际大小。

详细回答:

与许多其他编程语言不同,Go语言将数组的长度作为类型信息的一部分。因此,在Go语言中,没有仅仅是数组的类型,而是始终是具有特定大小的数组。例如,在下面的代码中,有两个int数组,一个是类型为[3]int,另一个是类型为[4]int,由于它们是不同的类型,将一个赋值给另一个是非法的。

package main

import (
	"fmt"
	"reflect"
)

func main() {
	a := [...]int{1, 2, 3}
	b := [...]int{1, 2, 3, 4}
	fmt.Println(reflect.TypeOf(a), reflect.TypeOf(b))
}

这个程序将[3]int [4]int打印到控制台,并说明了该程序中的ab是不同的类型(在Go Playground上查看)。由于它们是不同的类型,将a赋值给b(或反之亦然)是非法的,并且会导致编译错误:cannot use b (type [4]int) as type [3]int in assignment

[...]符号:[...]只能作为字面量的一部分使用,并且它表示编译器应该从字面量本身推断数组的长度。这样可以减轻程序员计算数组元素数量的负担。但是,仍然可以在字面量中指定大小,前提是字面量中的元素数量不超过指定的大小(在这种情况下,结果数组中的剩余元素为空)。例如,a := [4]int{1,2}是合法的,并且将创建这个数组:[1 2 0 0]

[...]符号不能用于变量声明,因此以下语句是无效的:var x [...]int。类似地,在你的示例中的结构体类型定义中,这个语句是非法的:f [...][]string,需要你指定数组的大小。

英文:

Short answer:

The notation [...] can be used to construct an array literal, but cannot be used in an array declaration. In the example you have provided, the [...] notation is used to declare a struct element. Hence the error. Replace [...] with [n], where n is the actual size of the array.

Long answer:

Unlike many other programming languages, Go includes the length of an array as part of type information. Hence, there is no type in Go that is just an array, but it is always an array of a specific size. For example, in the following code, there are two int arrays, where one is of type [3]int and the other is of type [4]int, and since they are of different types, assigning one to the other is illegal.

package main

import (
    "fmt"
    "reflect"
)

func main() {
    a := [...]int{1, 2, 3}
    b := [...]int{1, 2, 3, 4}
    fmt.Println(reflect.TypeOf(a), reflect.TypeOf(b))
}

This program prints [3]int [4]int to the console and illustrates that a and b in this program are of different types (find it here on the Go Playground). Since these are different types, assigning a to b (or vice versa) is illegal, and results in compilation error: cannot use b (type [4]int) as type [3]int in assignment

The [...] notation: The [...] can be used only as a part of a literal, and it indicates that the compiler should infer the length of array from the literal itself. This removes from a programmer the burden of counting the number of elements in the array. However, one may still specify a size in the literal, provided the literal has as many or fewer elements in it (in which case, the remaining elements in the resulting array are empty). For e.g. a := [4]int{1,2} is legal and will create this array: [1 2 0 0]

The [...] notation cannot be used in a variable declaration, and hence this statement is invalid: var x [...]int. Similarly, in the type definition of a struct of your example, this statement is illegal: f [...][]string, and requires that you specify the size of the array.

huangapple
  • 本文由 发表于 2014年11月25日 07:59:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/27116462.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定