2014-11-24 3 views
3

Я хочу создать составной литерал массивов массивов внутри структуры. Вне структурыСоздание составного литерала массива массивов

package main 

import "fmt" 

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

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

работает. (http://play.golang.org/p/C2RbNnd7LL)

Но я не могу определить поле типа [...] [] строки внутри структуры. Как и в 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) 
} 

е дает использование errror из [...] массив за пределами массива буквального

+0

Конечно, это дает ошибку! Массивы в Go имеют фиксированную длину времени компиляции. В качестве вежливости компилятор будет считать элементы массива ** literal ** для вас; это '...'. Нет литерала, нет счета, нет '...', просто укажите размер массива или перейдите к фрагменту. Взгляните на http://blog.golang.org/slices. И пожалуйста: Не называть срез массивом или наоборот (потому что каждый раз, когда кто-то умирает котенком). Это всего лишь синтаксическая ошибка в сочетании с непониманием массивов и фрагментов Go. Вы закончили тур Go? – Volker

+0

Может показаться вам несколько непривилегированных шаблонов здесь, но как только вы * сделаете * используете срезы, у вас есть несколько вариантов написания литералов: http://play.golang.org/p/X1Pwsp0nK2 – twotwotwo

ответ

1

Проблема заключается в том, что [...]elementType не является допустимым именем типа. Вы можете использовать синтаксис с синтаксисом инициализатора, например [...]int{1, 2, 3, 4}, потому что компилятор может видеть, сколько элементов существует для определения фактического типа ([4]int в этом случае).

Если вы хотите, тип массива типа, который не имеет фиксированный размер во время компиляции, используйте срез:

type t struct { 
    f [][]string 
} 

В качестве альтернативы, если число элементов фиксируется во время компиляции, и вы все еще хотите для использования массива вам нужно будет указать фактический счетчик элементов в определении вашего типа.

1

Короткий ответ:

Обозначения [...] можно использовать для создания массива буквальным, но не может быть использован в объявлении массива. В примере, который вы предоставили, нотация [...] используется для объявления элемента 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 и требует указания размера массива.

Смежные вопросы