Come dichiarare la mappa costante


126

Sto cercando di dichiarare costante in Go, ma genera un errore. Qualcuno potrebbe aiutarmi con la sintassi di dichiarare una costante in Go?

Questo è il mio codice:

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",
}

Questo è l'errore

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

Risposte:


154

La tua sintassi non è corretta. Per creare una mappa letterale (come pseudo-costante), puoi fare:

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",
}

All'interno di a funcpuoi dichiararlo come:

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

E in Go non esiste una mappa costante. Ulteriori informazioni possono essere trovate qui .

Provalo nel parco giochi Go.


1
Questo genera non-declaration statement outside function bodyeffettivamente un in fase di compilazione. Come mai?
alediaferia

@AlessandroDiaferia Non ricevo un tale errore. Come lo usi?
squiguy

7
@AlessandroDiaferia prova con var romanNumeralDict map[int]string = map[int]string{...}in tal caso.
B-Scan

4
@alediaferia ottieni quell'errore se usi :=al di fuori di una funzione.
Jeffrey Martinez

1
Cos'è una "pseudo-costante"?
Garrett

23

Puoi creare costanti in molti modi diversi:

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

Puoi anche creare una costante enum:

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

Non è possibile creare costanti di mappe, array ed è scritto in go effettivo :

Le costanti in Go sono proprio questo: costanti. Vengono creati in fase di compilazione, anche se definiti come locali nelle funzioni, e possono essere solo numeri, caratteri (rune), stringhe o booleani. A causa della limitazione del tempo di compilazione, le espressioni che le definiscono devono essere espressioni costanti, valutabili dal compilatore. Ad esempio, 1 << 3 è un'espressione costante, mentre math.Sin (math.Pi / 4) non lo è perché la chiamata di funzione a math.Sin deve avvenire in fase di esecuzione.


quindi è più simile a un constexpr C ++ 11 ... perché math.Sin non è una funzione constexpr, quindi!
Francesco Dondi

Le tue affermazioni sono corrette, ma la domanda riguardava la creazione di una mappa costante.
jzer7

5
@ jzer7 puoi spiegarmi perché la mia risposta è irrilevante? Mi ha chiesto come creare qualcosa, gli ho detto che questo non è possibile. Ha spiegato cosa è possibile e ha dato una citazione dai documenti perché esattamente non è possibile fare ciò che vuole.
Salvador Dali

12

Puoi emulare una mappa con una chiusura:

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

Provalo nel parco giochi Go


4
(TestMostSoldRecommender?)
volte il

1
È infatti una possibile soluzione. Tuttavia, poiché l'autore non ha spiegato nulla (e ha inserito tutto in un caso di test dal nome strano), la risposta sembra errata. La logica è: (1) Crea una funzione anonima (2) La funzione anonima incapsula la map(3) La funzione anonima restituisce "una funzione che accetta un int e restituisce una stringa" (4) La funzione restituita fa int -> stringa mappatura utilizzando map(5) Esegui immediatamente la funzione anonima e assegna la funzione restituita a una variabile. Questa variabile potrebbe essere utilizzata come una funzione e l'effetto è come una mappa.
Siu Ching Pong -Asuka Kenji-

3

E come suggerito sopra da Siu Ching Pong -Asuka Kenji con la funzione che secondo me ha più senso e ti lascia con la comodità del tipo di mappa senza la funzione wrapper intorno:

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

Prova questo su play.golang.org.


-2

Come indicato sopra, definire una mappa come costante non è possibile. Ma puoi dichiarare una variabile globale che è una struttura che contiene una mappa.

L'inizializzazione sarebbe simile a questa:

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

3
Perché non solo rendere la mappa la variabile globale? Perché avvolgerlo nella struttura?
Uragano Hamilton

3
Questo non rende la mappa costante, puoi ancora farloromanNumeralDict.m[1000] = "New value"
brando
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.