Короткий ответ:
Обозначения [...]
можно использовать для создания массива буквальным, но не может быть использован в объявлении массива. В примере, который вы предоставили, нотация [...]
используется для объявления элемента struct. Отсюда и ошибка. Замените [...]
на [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
на консоль и показывает, что a
и b
в этой программе имеют различные типы (найти его here on the 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
и требует указания размера массива.
Конечно, это дает ошибку! Массивы в Go имеют фиксированную длину времени компиляции. В качестве вежливости компилятор будет считать элементы массива ** literal ** для вас; это '...'. Нет литерала, нет счета, нет '...', просто укажите размер массива или перейдите к фрагменту. Взгляните на http://blog.golang.org/slices. И пожалуйста: Не называть срез массивом или наоборот (потому что каждый раз, когда кто-то умирает котенком). Это всего лишь синтаксическая ошибка в сочетании с непониманием массивов и фрагментов Go. Вы закончили тур Go? – Volker
Может показаться вам несколько непривилегированных шаблонов здесь, но как только вы * сделаете * используете срезы, у вас есть несколько вариантов написания литералов: http://play.golang.org/p/X1Pwsp0nK2 – twotwotwo