Кусочек разрезов
В настоящий момент я прохожу через отличный Tour of Go.
Я закончил одно из упражнений (№ 45) со следующим решением:
func Pic(dx, dy int) [][]uint8 {
pic := make([][]uint8, dy) /* type declaration */
for i := range pic {
pic[i] = make([]uint8, dx) /* again the type? */
for j := range pic[i] {
pic[i][j] = uint8((i+j)/2)
}
}
return pic
}
Я не понимаю, почему я должен использовать инструкцию make
с типом uint8
дважды (см. комментарии в фрагменте). Это кажется излишним, но я не могу понять, как это сделать другим способом.
Ответы
Ответ 1
В Go нет другого способа сделать это.
Да, я согласен, что это многословно, но необходимо. Второй оператор make() полностью не зависит от первого. Можно утверждать, что компилятор должен иметь возможность выводить тип из pic[i]
, но на данный момент этого не происходит.
Еще один момент: как выглядел бы оператор make(), если бы вы опустили тип во втором случае? Функция make() по-прежнему требуется для фактического распределения и для указания требуемой длины/емкости.
Как побочная заметка, вы перепутали длины срезов. Упражнение утверждает, что срез верхнего уровня должен иметь длину dy
, а не dx
по мере ввода кода.
Ответ 2
Чтобы быть явным, мы можем использовать круглые скобки для перезаписи [][]uint8
как []([]uint8)
: срез (фрагменты типа uint8
).
Используя сделать встроенную функцию, для фрагмента типа T
, make(T, n)
возвращает фрагмент типа T
с длиной n
и емкость n
.
Следовательно, make([][]uint8, 2)
эквивалентен make([]([]uint8), 2)
, он возвращает срез с длиной и емкостью 2
фрагментов типа uint8
, где каждый фрагмент типа uint8
инициализируется до нуля значение (a nil
ссылка с длиной и емкостью нуля).
Многомерные срезы зубчатые и аналогичны многомерным зубчатым массивам.
Например,
package main
import "fmt"
func main() {
ss := make([][]uint8, 2) // ss is []([]uint8)
fmt.Printf("ss: %T %v %d\n", ss, ss, len(ss))
for i, s := range ss { // s is []uint8
fmt.Printf("ss[%d]: %T %v %d\n", i, s, s, len(s))
}
}
Вывод:
ss: [][]uint8 [[] []] 2
ss[0]: []uint8 [] 0
ss[1]: []uint8 [] 0