2010-10-18 2 views
3

В настоящее время я играю с Google Go.
Существует множество способов объявить и/или инициализировать переменные.
Может кто-то объясняет, плюсы/минусы каждого пути (образцы, насколько я знаю, ниже):Предпочтительный метод declare/initialize

var strArr0 *[10]string = new([10]string) 

    var strArr1 = new([10]string) 

    var strArr2 = make([]string,10) 

    var strArr3 [10]string 

    strArr4 := make([]string,10) 

Что вы предпочитаете синтаксис, и почему?
Спасибо, ТАК народ!

ответ

7

Я пронумеровал свои примеры 1-5, и я буду ходить через их здесь. Надеюсь, это поможет!

var strArr0 *[10]string = new([10]string) // (1) 

Это выделяет новый массив строк длиной 10 и возвращает указатель на массив.

var strArr1 = new([10]string) // (2) 

Это точно так же, как 1. Это просто сокращение, которое работает из-за вывода типа Go. Он может быть сокращен далее до:

strArr1 := new([10]string) // (2a) 

Где 1, 2, 2a все производят точно такой же результат.

var strArr2 = make([]string,10) // (3) 

Это делает кусок строк длиной 10. Кусочек относится к некоторому подмножеству базового массива. От the golang spec:

Информация о производителе() вызов выделяет новый, скрытый массив, к которому относится возвращаемый значение среза.

make([]T, length, capacity) 

производит тот же срез, как выделение массива и нарезки его, так что эти два примера привести к одной и той же среза:

make([]int, 50, 100) 
new([100]int)[0:50] 

Так 3 эквивалент любого из следующего:

var strArr2 = new([10]string)[0:10] // Slicing an explicitly created array 
var strArr2 []string = new([10]string)[0:10] // Explicitly declaring the type of strArr2, rather than inferring 
strArr2 := new([10]string)[0:10] // Using the := shorthand instead of var 

новый или make используется в зависимости от того, какой тип вы создаете. make используется исключительно для фрагментов, карт и каналов. Они использовали другое ключевое слово, чтобы передать идею, что make инициализирует некоторую структуру данных под капотом, а не просто обнуляет память.

Следующий возвращается в массивы, а не ломтиков:

var strArr3 [10]string // (4) 

Это то же самое, как 1, 2 и 2а.

strArr4 := make([]string,10) // (5) 

То же, что и 3.: = является просто сокращением при инициализации переменной, и тип может быть выведен.


Так что выбрать? Это немного зависит от вашего личного стиля, но в целом один из вариантов, очевидно, будет максимизировать ясность вашего кода, например. с помощью логического вывода типа, когда тип очевиден:

foo := bar.ToStringArray() 

или объявления типов, когда это меньше, так и тип будет полезно посмотреть:

var foo []string = bar.DoSomethingOpaque() 

на кусочки по сравнению с массивами, вы обычно создают любой тип необходим для какой-либо функции, которую вы вызываете.

2

Прежде всего, вы должны понимать различие между массивами и срезами. Массивы рассматриваются как значения, поэтому, если вы передадите их в функции, они будут скопированы. Срезки, с другой стороны, являются ссылками на базовый массив, поэтому, если вы передаете срез функции, переменная функции по-прежнему будет ссылаться на один и тот же базовый массив.

В ваших примерах первые два идентичны, это только первый указывает тип объявления переменной. Идите, давайте сделаем это, и это может помочь в некоторых случаях - например, когда вы пытаетесь объявить переменную как интерфейс вместо значения (например, var i io.Reader = os.Open (...)) ,

Третий и пятый (var strArr2 = make([]string,10), strArr4 := make([]string,10) эквивалентны, но последние использует форму коротких рук объявления переменного, которая часто может сэкономить много печатать.

Четвертый раз объявляет значение массива. .

Я редко иметь дело с массивами в моем коде, если я не буду работать с сетевыми данными Так что мой предпочтительный синтаксис:

s := make([]string, 10) 
+0

Не могли бы вы указать разницу в подходах 1 и 2 и 3 и 5? Я понимаю, что 1 и 2 и 3 и 5 одинаковы, но я не уверен, когда/почему использовать один над другим. – jlv

+0

Мне никогда не приходилось использовать строковые массивы фиксированного размера (1 или 2), но я все время использую срезы массивов строк (3 и 5), потому что это вектор vector.StringVector. Я работал с массивами фиксированного размера при анализе сетевых данных. Например, читатель [zlib reader] (http://golang.org/src/pkg/compress/zlib/reader.go) читает некоторые параметры кодирования в массиве фиксированного размера 'scratch [4] byte'. – marketer

+0

Btw, даже если 4), кажется, объявляет значение массива без его инициализации, то есть без использования 'new' или 'make', это (удивительно?) Все еще можно заполнить связанным массивом: var strArr3 [10] строка strArr3 [0] = "бла" os.Stdout.WriteString (strArr3 [0] + "\ п") отображает "бла". – jideel

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