70 votes

Types de tranches

Je travaille actuellement à la lecture de l'excellent Tour de 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 un make avec la déclaration uint8 deux fois (voir les commentaires dans l'extrait). Cela semble redondant mais je ne vois pas comment faire autrement.

38voto

peterSO Points 25725

Pour être explicite, nous pouvons utiliser des parenthèses pour réécrire [][]uint8 como []([]uint8) : une tranche de (tranches de type uint8 ).

L'utilisation de la faire pour une tranche de type T , make(T, n) renvoie une tranche de type T avec longueur n et la capacité n .

C'est pourquoi, make([][]uint8, 2) est équivalent à make([]([]uint8), 2) il renvoie une tranche, d'une longueur et d'une capacité de 2 de tranches de type uint8 où chaque tranche de type uint8 est initialisé à sa valeur zéro (a nil avec une longueur et une capacité de zéro).

Les coupes multidimensionnelles sont irrégulières et sont analogues aux coupes multidimensionnelles. tableaux en dents de scie .

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))
    }
}

Salida:

ss:    [][]uint8 [[] []] 2
ss[0]: []uint8 [] 0
ss[1]: []uint8 [] 0

35voto

jimt Points 7028

Il n'y a pas d'autre moyen de le faire en Go.

Oui, je suis d'accord, c'est verbeux, mais c'est nécessaire. La deuxième instruction make() est totalement indépendante de la première. On pourrait argumenter que le compilateur devrait être capable de déduire le type à partir de pic[i] mais ce n'est pas le cas à ce stade.

Autre point : à quoi ressemblerait l'instruction make() si l'on omettait le type dans le second cas ? Le make() est toujours nécessaire pour effectuer l'allocation réelle et pour pouvoir spécifier la longueur/capacité requise.

Par ailleurs, vous avez mélangé les longueurs des tranches. L'exercice indique que la tranche de niveau supérieur doit avoir une longueur de dy , pas dx comme vous l'avez fait dans votre code.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X