Déclarer un tableau constant

164

J'ai essayé:

const ascii = "abcdefghijklmnopqrstuvwxyz"
const letter_goodness []float32  = { .0817,.0149,.0278,.0425,.1270,.0223,.0202, .0609,.0697,.0015,.0077,.0402,.0241,.0675, .0751,.0193,.0009,.0599,.0633,.0906,.0276, .0098,.0236,.0015,.0197,.0007 }
const letter_goodness  = { .0817,.0149,.0278,.0425,.1270,.0223,.0202, .0609,.0697,.0015,.0077,.0402,.0241,.0675, .0751,.0193,.0009,.0599,.0633,.0906,.0276, .0098,.0236,.0015,.0197,.0007 }
const letter_goodness = []float32 { .0817,.0149,.0278,.0425,.1270,.0223,.0202, .0609,.0697,.0015,.0077,.0402,.0241,.0675, .0751,.0193,.0009,.0599,.0633,.0906,.0276, .0098,.0236,.0015,.0197,.0007 }

Premièrement, la déclaration et l'initialisation fonctionnent bien, mais les deuxième, troisième et quatrième ne fonctionnent pas. Comment puis-je déclarer et initialiser un tableau const de flottants?

demas
la source

Réponses:

232

Un tableau n'est pas immuable par nature; vous ne pouvez pas le rendre constant.

Le plus proche que vous pouvez obtenir est:

var letter_goodness = [...]float32 {.0817, .0149, .0278, .0425, .1270, .0223, .0202, .0609, .0697, .0015, .0077, .0402, .0241, .0675, .0751, .0193, .0009, .0599, .0633, .0906, .0276, .0098, .0236, .0015, .0197, .0007 }

Notez le [...]au lieu de []: il garantit que vous obtenez un tableau (de taille fixe) au lieu d'une tranche. Donc, les valeurs ne sont pas fixes mais la taille l'est.

Denys Séguret
la source
126
Juste pour clarifier: la [...]Tsyntaxe est pour le sucre [123]T. Il crée un tableau de taille fixe, mais laisse le compilateur déterminer le nombre d'éléments qu'il contient.
jimt
5
Je suppose que permettre des tableaux constants nécessiterait des mises à jour du système de types. Sinon, si vous définissez une fonction, f(xs [5]int)vous ne saurez pas si le tableau passé est constant ou mutable.
Thomas Ahle
tks, j'ai des problèmes quand j'essaye de cordes.Join cannot use constants.FilesRequired (type [4]string) as type []string in argument to strings.Join
Eddy Hernandez
Merci pour la solution de tranche. Doute: un tableau lui-même est immuable, non? On ne peut pas ajouter ou supprimer des éléments une fois qu'un tableau est créé, non? Je peux cependant modifier les éléments du tableau.
legends2k
@ legends2k Vous ne pouvez pas changer la taille du tableau, oui, mais vous pouvez mettre d'autres valeurs dans ses emplacements.
Denys Séguret
63

De Effective Go :

Les constantes de Go ne sont que cela - constantes. Ils sont créés au moment de la compilation, même lorsqu'ils sont définis comme locaux dans les fonctions, et ne peuvent être que des nombres, des chaînes ou des booléens. En raison de la restriction de compilation, les expressions qui les définissent doivent être des expressions constantes, évaluables par le compilateur. Par exemple, 1 << 3 est une expression constante, tandis que math.Sin (math.Pi / 4) ne l'est pas parce que l'appel de fonction à math.Sin doit se produire au moment de l'exécution.

Les tranches et les tableaux sont toujours évalués lors de l'exécution:

var TestSlice = []float32 {.03, .02}
var TestArray = [2]float32 {.03, .02}
var TestArray2 = [...]float32 {.03, .02}

[...]indique au compilateur de déterminer la longueur du tableau lui-même. Les tranches enveloppent les tableaux et sont plus faciles à utiliser dans la plupart des cas. Au lieu d'utiliser des constantes, rendez simplement les variables inaccessibles aux autres packages en utilisant une première lettre minuscule:

var ThisIsPublic = [2]float32 {.03, .02}
var thisIsPrivate = [2]float32 {.03, .02}

thisIsPrivateest disponible uniquement dans le package défini. Si vous avez besoin d'un accès en lecture de l'extérieur, vous pouvez alors écrire une simple fonction getter (voir Getters en golang ).

fasmat
la source
12

Il n'y a pas de constante de tableau dans Go.

Citations de la spécification du langage Go: Constantes :

Il existe des constantes booléennes , constantes rune , constantes entières , des constantes à virgule flottante , des constantes complexes et constantes de chaîne . Les constantes runiques, entières, à virgule flottante et complexes sont collectivement appelées constantes numériques .

Une expression Constante (utilisée pour initialiser une constante) peut contenir uniquement des opérandes constants et est évaluée au moment de la compilation.

La spécification répertorie les différents types de constantes. Notez que vous pouvez créer et initialiser des constantes avec des expressions constantes de types ayant l'un des types autorisés comme type sous- jacent . Par exemple ceci est valide:

func main() {
    type Myint int
    const i1 Myint = 1
    const i2 = Myint(2)
    fmt.Printf("%T %v\n", i1, i1)
    fmt.Printf("%T %v\n", i2, i2)
}

Sortie (essayez-le sur le Go Playground ):

main.Myint 1
main.Myint 2

Si vous avez besoin d'un tableau, il ne peut s'agir que d'une variable, mais pas d'une constante.

Je recommande cet excellent article de blog sur les constantes: Constantes

icza
la source
alors que faire si besoin d'un conteneur de taille constante?
@Atomic_alarm Pouvez-vous élaborer s'il vous plaît?
icza
Existe que ce soit dans le C-array analogique golang?
@Atomic_alarm Oui, les tableaux existent aussi dans Go, ce ne sont tout simplement pas des expressions constantes, ils sont évalués à l'exécution. Ainsi, une constante ne peut pas être de type tableau, mais une variable le peut. Par exemple:var arr = [2]int{2, 3}
icza
3

Comme d'autres l'ont mentionné, il n'y a pas de construction officielle de Go pour cela. Le plus proche que je puisse imaginer serait une fonction qui renvoie une tranche. De cette manière, vous pouvez garantir que personne ne manipulera les éléments de la tranche d'origine (car elle est "codée en dur" dans le tableau).

J'ai raccourci votre tranche pour la rendre ... plus courte ...:

func GetLetterGoodness() []float32 {
    return [...]float32 { .0817,.0149,.0278,.0425,.1270,.0223 }
}
Paul
la source
4
cela semble être la meilleure façon de procéder, mais le type de retour func ne correspond pas. cannot use [6]string literal (type [6]string) as type []string in return argumentsoreturn []float32 { ... }
theRemix
@theRemix Trois correctifs possibles: (1) supprimer ...afin de déclarer un littéral de tranche au lieu d'un littéral de tableau. (2) changez le type de retour en [6]float32. (3) attribuer à l'expression d' une variable de réseau, a := [...]float32 { (etc.) }et renvoyer la tranche de tous les éléments: return a[:]. (Les littéraux de tableau ne sont pas adressables, je ne sais pas pourquoi.)
David Moles
Je ne sais pas ce que vous voulez dire. Il semble que vous essayez de résoudre quelque chose dans votre code qui est probablement mieux résolu avec des tests (unitaires).
Dynom