Bagaimana mendeklarasikan peta konstan

126

Saya mencoba untuk menyatakan konstan di Go, tetapi itu membuat kesalahan. Adakah yang bisa membantu saya dengan sintaks mendeklarasikan konstanta di Go?

Ini kode saya:

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

Ini adalah kesalahannya

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

Jawaban:

154

Sintaks Anda salah. Untuk membuat peta literal (sebagai konstanta semu), Anda dapat melakukan:

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

Di dalam a funcAnda bisa mendeklarasikannya seperti:

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

Dan di Go tidak ada yang namanya peta konstan. Informasi lebih lanjut dapat ditemukan di sini .

Cobalah di taman bermain Go.

squiguy
sumber
1
Ini melempar non-declaration statement outside function bodypada waktu kompilasi sebenarnya. Bagaimana bisa?
alediaferia
@AlessandDiaferia Saya tidak mendapatkan kesalahan seperti itu. Bagaimana Anda menggunakannya?
squiguy
7
@AlessandroDiaferia coba var romanNumeralDict map[int]string = map[int]string{...}dalam kasus seperti itu.
B-Scan
4
@alediaferia Anda mendapatkan kesalahan itu jika menggunakan di :=luar fungsi.
Jeffrey Martinez
1
Apa itu "pseudo-konstan"?
Garrett
23

Anda dapat membuat konstanta dengan berbagai cara:

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

Anda juga dapat membuat konstanta enum:

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

Anda tidak dapat membuat konstanta peta, array, dan ini ditulis dengan efektif :

Konstanta dalam Go hanya itu — konstan. Mereka dibuat pada waktu kompilasi, bahkan ketika didefinisikan sebagai lokal dalam fungsi, dan hanya dapat berupa angka, karakter (rune), string atau boolean. Karena batasan waktu kompilasi, ekspresi yang mendefinisikannya harus berupa ekspresi konstan, yang dapat dievaluasi oleh kompilator. Misalnya, 1 << 3 adalah ekspresi konstan, sedangkan math.Sin (math.Pi / 4) bukan karena pemanggilan fungsi math.Sin perlu terjadi pada waktu proses.

Salvador Dali
sumber
jadi lebih seperti C ++ 11 constexpr ... mengapa math.Sin bukan fungsi constexpr, kalau begitu!
Francesco Dondi
Pernyataan Anda benar, tetapi pertanyaannya adalah tentang membuat peta yang konstan.
jzer7
5
@ jzer7 dapatkah Anda menjelaskan mengapa jawaban saya tidak relevan? Dia bertanya bagaimana membuat sesuatu, saya katakan kepadanya bahwa ini tidak mungkin. Menjelaskan apa yang mungkin dan memberikan kutipan dari dokumen mengapa sebenarnya tidak mungkin untuk melakukan apa yang dia inginkan.
Salvador Dali
12

Anda dapat meniru peta dengan penutupan:

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

Cobalah di taman bermain Go

oleber
sumber
4
(TestMostSoldRecommender?)
dua kali dua kali
1
Ini sebenarnya adalah solusi yang mungkin. Namun, karena penulis tidak menjelaskan apa pun (dan memasukkan semuanya ke dalam kasus uji yang diberi nama aneh), jawabannya terlihat salah. Logikanya adalah: (1) Buat fungsi anonim (2) Fungsi anonim merangkum map(3) Fungsi anonim mengembalikan "fungsi yang menerima int dan mengembalikan string" (4) Fungsi yang dikembalikan melakukan int -> string pemetaan dengan menggunakan map(5) Jalankan fungsi anonim segera dan tetapkan fungsi yang dikembalikan ke variabel. Variabel ini bisa digunakan seperti fungsi, dan efeknya seperti peta.
Siu Ching Pong -Asuka Kenji-
3

Dan seperti yang disarankan di atas oleh Siu Ching Pong-Asuka Kenji dengan fungsi yang menurut saya lebih masuk akal dan memberi Anda kenyamanan tipe peta tanpa fungsi pembungkus di sekitarnya:

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

Coba ini di play.golang.org.

Denis Volin
sumber
-2

Seperti yang dinyatakan di atas untuk mendefinisikan peta sebagai konstanta tidak mungkin. Tapi Anda bisa mendeklarasikan variabel global yang merupakan struct yang berisi peta.

Inisialisasi akan terlihat seperti ini:

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
sumber
3
Mengapa tidak hanya membuat peta sebagai variabel global? Mengapa membungkusnya di struct?
Badai Hamilton
3
Ini tidak membuat peta konstan, Anda masih bisa melakukannyaromanNumeralDict.m[1000] = "New value"
brando