Je travaille actuellement mon chemin à travers l'excellent Tour of Go . J'ai terminé l'un des exercices (# 45) avec la solution suivante:
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
}
Je ne comprends pas pourquoi je dois utiliser une instruction make
avec le uint8
tapez deux fois (voir les commentaires dans l'extrait). Cela semble redondant mais je n'arrive pas à comprendre comment le faire d'une autre manière.
Il n'y a pas d'autre moyen de le faire dans Go.
Oui, je suis d'accord, c'est verbeux, mais nécessaire. La deuxième instruction make () est entièrement indépendante de la première. On pourrait faire valoir que le compilateur devrait pouvoir déduire le type de pic[i]
, mais ce n'est pas le cas à ce stade.
Autre point: à quoi ressemblerait l'instruction make () si vous omettiez le type dans le deuxième cas? Le make () est toujours requis pour effectuer l'allocation réelle et pouvoir spécifier la longueur/capacité requise.
En remarque, vous avez mélangé les longueurs de tranche. L'exercice indique que la tranche de niveau supérieur doit avoir une longueur dy
, et non dx
comme vous l'avez mise dans votre code.
Pour être explicite, nous pouvons utiliser des parenthèses pour réécrire [][]uint8
En []([]uint8)
: une tranche de (tranches de type uint8
).
En utilisant la fonction intégrée make , pour une tranche de type T
, make(T, n)
renvoie une tranche de type T
de longueur n
et capacité n
.
Par conséquent, make([][]uint8, 2)
est équivalent à make([]([]uint8), 2)
, il renvoie une tranche, avec une longueur et une capacité de 2
, De tranches de type uint8
, Où chaque tranche de type uint8
est initialisée à sa valeur zéro (une référence nil
avec une longueur et une capacité de zéro).
Les tranches multidimensionnelles sont dentelées et sont analogues aux multidimensionnelles tableaux dentelés .
Par exemple,
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))
}
}
Production:
ss: [][]uint8 [[] []] 2
ss[0]: []uint8 [] 0
ss[1]: []uint8 [] 0