So deklarieren Sie eine konstante Karte

125

Ich versuche, in Go die Konstante zu deklarieren, aber es wird ein Fehler ausgegeben. Könnte mir bitte jemand bei der Syntax helfen, eine Konstante in Go zu deklarieren?

Das ist mein 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",
}

Dies ist der Fehler

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

Antworten:

153

Ihre Syntax ist falsch. Um eine Literalkarte (als Pseudokonstante) zu erstellen, haben Sie folgende Möglichkeiten:

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

In a können funcSie es wie folgt deklarieren:

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

Und in Go gibt es keine konstante Karte. Weitere Informationen finden Sie hier .

Probieren Sie es auf dem Go-Spielplatz aus.

squiguy
quelle
1
Dies wirft non-declaration statement outside function bodytatsächlich eine Kompilierungszeit. Woher?
Alediaferia
@AlessandroDiaferia Ich bekomme keinen solchen Fehler. Wie benutzt du es?
Squiguy
7
@AlessandroDiaferia versuchen Sie es var romanNumeralDict map[int]string = map[int]string{...}in einem solchen Fall.
B-Scan
4
@alediaferia Sie erhalten diesen Fehler, wenn Sie :=außerhalb einer Funktion verwenden.
Jeffrey Martinez
1
Was ist eine "Pseudokonstante"?
Garrett
23

Sie können Konstanten auf viele verschiedene Arten erstellen:

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

Sie können auch eine Aufzählungskonstante erstellen:

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

Sie können keine Konstanten von Maps, Arrays erstellen und es ist in effektiver Form geschrieben :

Konstanten in Go sind genau das - Konstante. Sie werden zur Kompilierungszeit erstellt, auch wenn sie in Funktionen als lokale Elemente definiert sind. Sie können nur Zahlen, Zeichen (Runen), Zeichenfolgen oder Boolesche Werte sein. Aufgrund der Einschränkung der Kompilierungszeit müssen die Ausdrücke, die sie definieren, konstante Ausdrücke sein, die vom Compiler ausgewertet werden können. Zum Beispiel ist 1 << 3 ein konstanter Ausdruck, während math.Sin (math.Pi / 4) dies nicht ist, weil der Funktionsaufruf von math.Sin zur Laufzeit erfolgen muss.

Salvador Dali
quelle
es ist also eher wie ein C ++ 11-Constexpr ... warum math.Sin also keine Constexpr-Funktion ist!
Francesco Dondi
Ihre Aussagen sind korrekt, aber die Frage war, eine Karte zu erstellen, die konstant ist.
jzer7
5
@ jzer7 kannst du mir erklären warum meine antwort irrelevant ist? Er fragte, wie man etwas erschafft, ich sagte ihm, dass dies nicht möglich ist. Erklärte, was möglich ist und zitierte aus den Dokumenten, warum genau es nicht möglich ist, das zu tun, was er will.
Salvador Dali
12

Sie können eine Karte mit einem Abschluss emulieren:

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

Probieren Sie es auf dem Go-Spielplatz aus

oleber
quelle
4
(TestMostSoldRecommender?)
Zwei
1
Es ist in der Tat eine mögliche Lösung. Da der Autor jedoch nichts erklärt hat (und alles in einen seltsam benannten Testfall gesteckt hat), sieht die Antwort falsch aus. Die Logik lautet: (1) Erstellen einer anonymen Funktion (2) Die anonyme Funktion kapselt die map(3) Die anonyme Funktion gibt "eine Funktion zurück, die ein int akzeptiert und eine Zeichenfolge zurückgibt". (4) Die zurückgegebene Funktion führt die Zeichenfolge int -> aus Mapping mit map(5) Führen Sie die anonyme Funktion sofort aus und weisen Sie die zurückgegebene Funktion einer Variablen zu. Diese Variable kann wie eine Funktion verwendet werden, und der Effekt ist wie eine Karte.
Siu Ching Pong -Asuka Kenji-
3

Und wie oben von Siu Ching Pong-Asuka Kenji mit der Funktion vorgeschlagen, die meiner Meinung nach sinnvoller ist und Ihnen den Komfort des Kartentyps ohne den Funktionsumbruch bietet:

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

Versuchen Sie dies auf play.golang.org.

Denis Volin
quelle
-2

Wie oben angegeben, ist es nicht möglich, eine Karte als konstant zu definieren. Sie können jedoch eine globale Variable deklarieren, bei der es sich um eine Struktur handelt, die eine Karte enthält.

Die Initialisierung würde folgendermaßen aussehen:

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
quelle
3
Warum nicht einfach die Karte zur globalen Variablen machen? Warum in die Struktur einwickeln?
Hurrikan Hamilton
3
Dies macht die Karte nicht konstant, Sie können es immer noch tunromanNumeralDict.m[1000] = "New value"
Brando