Comment déclarer une carte constante

126

J'essaie de déclarer une constante dans Go, mais cela génère une erreur. Quelqu'un pourrait-il m'aider s'il vous plaît avec la syntaxe de la déclaration d'une constante dans Go?

Voici mon code:

const romanNumeralDict map[int]string = {
  1000: "M",
  900 : "CM",
  500 : "D",
  400 : "CD",
  100 : "C",
  90  : "XC",
  50  : "L",
  40  : "XL",
  10  : "X",
  9   : "IX",
  5   : "V",
  4   : "IV",
  1   : "I",
}

C'est l'erreur

# command-line-arguments
./Roman_Numerals.go:9: syntax error: unexpected {
samol
la source

Réponses:

154

Votre syntaxe est incorrecte. Pour créer une carte littérale (sous forme de pseudo-constante), vous pouvez faire:

var romanNumeralDict = map[int]string{
  1000: "M",
  900 : "CM",
  500 : "D",
  400 : "CD",
  100 : "C",
  90  : "XC",
  50  : "L",
  40  : "XL",
  10  : "X",
  9   : "IX",
  5   : "V",
  4   : "IV",
  1   : "I",
}

À l'intérieur d'un, funcvous pouvez le déclarer comme:

romanNumeralDict := map[int]string{
...

Et dans Go, il n'y a pas de carte constante. Plus d'informations peuvent être trouvées ici .

Essayez-le sur le terrain de jeu Go.

squiguy
la source
1
Cela lève un non-declaration statement outside function bodyau moment de la compilation en fait. Comment venir?
alediaferia
@AlessandroDiaferia Je n'obtiens pas une telle erreur. Comment l'utilisez-vous?
squiguy
7
@AlessandroDiaferia essayez avec var romanNumeralDict map[int]string = map[int]string{...}dans ce cas.
B-Scan
4
@alediaferia vous obtenez cette erreur si vous utilisez en :=dehors d'une fonction.
Jeffrey Martinez
1
Qu'est-ce qu'une "pseudo-constante"?
Garrett
23

Vous pouvez créer des constantes de différentes manières:

const myString = "hello"
const pi = 3.14 // untyped constant
const life int = 42 // typed constant (can use only with ints)

Vous pouvez également créer une constante d'énumération:

const ( 
   First = 1
   Second = 2
   Third = 4
)

Vous ne pouvez pas créer de constantes de maps, de tableaux et c'est écrit en bon go :

Les constantes dans Go ne sont que cela - constante. 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 caractères (runes), 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.

Salvador Dali
la source
donc c'est plus comme une constexpr C ++ 11 ... pourquoi math.Sin n'est pas une fonction constexpr, alors!
Francesco Dondi
Vos déclarations sont correctes, mais la question portait sur la création d'une carte constante.
jzer7
5
@ jzer7 pouvez-vous m'expliquer pourquoi ma réponse n'est pas pertinente? Il a demandé comment créer quelque chose, je lui ai dit que ce n'était pas possible. Expliqué ce qui est possible et cité dans la documentation pourquoi il n'est pas possible de faire exactement ce qu'il veut.
Salvador Dali
12

Vous pouvez émuler une carte avec une fermeture:

package main

import (
    "fmt"
)

// http://stackoverflow.com/a/27457144/10278

func romanNumeralDict() func(int) string {
    // innerMap is captured in the closure returned below
    innerMap := map[int]string{
        1000: "M",
        900:  "CM",
        500:  "D",
        400:  "CD",
        100:  "C",
        90:   "XC",
        50:   "L",
        40:   "XL",
        10:   "X",
        9:    "IX",
        5:    "V",
        4:    "IV",
        1:    "I",
    }

    return func(key int) string {
        return innerMap[key]
    }
}

func main() {
    fmt.Println(romanNumeralDict()(10))
    fmt.Println(romanNumeralDict()(100))

    dict := romanNumeralDict()
    fmt.Println(dict(400))
}

Essayez-le sur le terrain de jeu Go

olébre
la source
4
(TestMostSoldRecommender?)
twotwotwo
1
C'est en fait une solution possible. Cependant, puisque l'auteur n'a rien expliqué (et a tout mis dans un cas de test au nom étrange), la réponse semble incorrecte. La logique est: (1) Créer une fonction anonyme (2) La fonction anonyme encapsule le map(3) La fonction anonyme renvoie "une fonction qui accepte un int et retourne une chaîne" (4) La fonction retournée fait le int -> string mapping à l'aide du map(5) Exécuter immédiatement la fonction anonyme et affecter la fonction retournée à une variable. Cette variable peut être utilisée comme une fonction, et l'effet est comme une carte.
Siu Ching Pong -Asuka Kenji-
3

Et comme suggéré ci-dessus par Siu Ching Pong -Asuka Kenji avec la fonction qui, à mon avis, a plus de sens et vous laisse avec la commodité du type de carte sans le wrapper de fonction:

   // romanNumeralDict returns map[int]string dictionary, since the return
       // value is always the same it gives the pseudo-constant output, which
       // can be referred to in the same map-alike fashion.
       var romanNumeralDict = func() map[int]string { return map[int]string {
            1000: "M",
            900:  "CM",
            500:  "D",
            400:  "CD",
            100:  "C",
            90:   "XC",
            50:   "L",
            40:   "XL",
            10:   "X",
            9:    "IX",
            5:    "V",
            4:    "IV",
            1:    "I",
          }
        }

        func printRoman(key int) {
          fmt.Println(romanNumeralDict()[key])
        }

        func printKeyN(key, n int) {
          fmt.Println(strings.Repeat(romanNumeralDict()[key], n))
        }

        func main() {
          printRoman(1000)
          printRoman(50)
          printKeyN(10, 3)
        }

Essayez ceci sur play.golang.org.

Denis Volin
la source
-2

Comme indiqué ci-dessus, il n'est pas possible de définir une carte comme constante. Mais vous pouvez déclarer une variable globale qui est une structure contenant une carte.

L'initialisation ressemblerait à ceci:

var romanNumeralDict = struct {
    m map[int]string
}{m: map[int]string {
    1000: "M",
    900: "CM",
    //YOUR VALUES HERE
}}

func main() {
    d := 1000
    fmt.Printf("Value of Key (%d): %s", d, romanNumeralDict.m[1000])
}
inde
la source
3
Pourquoi ne pas simplement faire de la carte la variable globale? Pourquoi l'envelopper dans la structure?
Hurricane Hamilton le
3
Cela ne rend pas la carte constante, vous pouvez toujours le faireromanNumeralDict.m[1000] = "New value"
brando