web-dev-qa-db-fra.com

Tranche de types de tranches

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.

62
harm

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.

33
jimt

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
34
peterSO