Creating a composite array literal of arrays

I want to create a composite array literal of arrays inside a struct. Out of structure

package main

import "fmt"

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

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

      

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

But I cannot define a field of type [...] [] string inside the structure. 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 use of an array errror [...] outside of an array literal

+3


source to share


2 answers


The problem is that [...]elementType

it is not a valid type name. You can use the syntax with the initialiser syntax, for example [...]int{1, 2, 3, 4}

, because the compiler can see how many elements exist to determine the actual type ( [4]int

in this case).

If you want an array type that doesn't have a compile-time fixed 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 provide the actual count of the elements in your type definition.

+1


source


The short answer is:

The notation [...]

can be used to construct an array literal, but cannot be used in an array declaration. In the example you provided, the notation is [...]

used to declare a structure member. 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 the array as part of its type information. Therefore, there is no type in Go that is just an array, but it is always an array of a certain 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, it is illegal to assign one of them.



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 displays [3]int [4]int

on the console and shows that a

and b

are of different types in the program (look here at the Playground's the Go ). Since they are different types, assignment a

to b

(or vice versa) is illegal and results in a compilation error:cannot use b (type [4]int) as type [3]int in assignment

Notation [...]

: [...]

can only be used as part of a literal, and indicates that the compiler should infer the length of the array from the literal itself. This relieves the programmer of the burden of counting the number of elements in the array. However, it is still possible to specify the size in a literal if the literal has so many or fewer elements in it (in which case the rest of the elements in the resulting array are empty). Ex. a := [4]int{1,2}

is legal and will create this array:[1 2 0 0]

The designation [...]

may not be used to declare a variable, and therefore, this statement is not valid: var x [...]int

. Likewise, in your example's structure type definition, this statement is illegal: f [...][]string

and requires you to specify the size of the array.

+1


source







All Articles