定数マップを宣言する方法


125

Goで定数を宣言しようとしていますが、エラーがスローされます。Goで定数を宣言する構文について誰かが私を助けてくれませんか?

これは私のコードです:

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

これはエラーです

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

回答:


153

構文が正しくありません。(疑似定数として)リテラルマップを作成するには、次のようにします。

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

内部では、func次のように宣言できます。

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

そしてGoでは、定数マップのようなものはありません。詳細については、こちらをご覧ください

Goプレイグラウンドで試してみてください。


1
これはnon-declaration statement outside function bodyコンパイル時に実際にスローされます。どうして?
アレディアフェリア2014

@AlessandroDiaferiaこのようなエラーは発生しません。どのように使用していますか?
squiguy 2014

7
@AlessandroDiaferia var romanNumeralDict map[int]string = map[int]string{...}はそのような場合に試します。
B-Scan

4
@alediaferia :=関数の外で使用すると、そのエラーが発生します。
Jeffrey Martinez

1
「疑似定数」とは何ですか?
ギャレット

23

定数はさまざまな方法で作成できます。

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

列挙定数を作成することもできます:

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

マップ、配列の定数を作成することはできず、効果的なgoで記述されています

Goの定数はまさに定数です。関数でローカルとして定義されている場合でも、コンパイル時に作成され、数字、文字(ルーン)、文字列、またはブール値のみを使用できます。コンパイル時の制限のため、それらを定義する式は、コンパイラーが評価できる定数式でなければなりません。たとえば、1 << 3は定数式ですが、math.Sin(math.Pi / 4)は、math.Sinへの関数呼び出しを実行時に行う必要があるため、そうではありません。


つまり、C ++ 11のconstexprに似ています...では、math.Sinがconstexpr関数ではないのはなぜでしょうか。
Francesco Dondi

あなたの発言は正しいですが、問題は一定したマップを作成することでした。
jzer7 2016年

5
@ jzer7私の答えが無関係である理由を私に説明できますか?彼は何かを作る方法を尋ねました、私はこれは不可能だと彼に言いました。何が可能であるかを説明し、ドキュメントから、彼が望むことを正確に行うことができない理由を引用しました。
サルバドールダリ

12

クロージャーでマップをエミュレートできます:

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

囲碁の遊び場で試してみる


4
(TestMostSoldRecommender?)
twotwotwo 14

1
それは実際に可能な解決策です。ただし、作成者は何も説明しなかった(そしてすべてを奇妙な名前のテストケースに入れた)ため、答えは正しくないように見えます。ロジックは次のとおりです:(1)匿名関数を作成します(2)匿名関数はmap(3)をカプセル化しますmap(5)を使用したマッピング匿名関数をすぐに実行し、返された関数を変数に割り当てます。この変数は関数のように使用でき、効果はマップのようです。
Siu Ching Pong -Asuka Kenji-

3

そして上記のSiu Ching Pong -Asuka Kenjiが提案したように、私の意見ではより意味があり、関数ラッパーなしでマップタイプの利便性を提供します。

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

play.golang.orgでこれを試してください。


-2

上記のとおり、マップを定数として定義することはできません。ただし、マップを含む構造体であるグローバル変数を宣言できます。

初期化は次のようになります。

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
なぜマップをグローバル変数にしないのですか?なぜそれを構造体でラップするのですか?
ハリケーンハミルトン

3
これはマップを一定にしませんが、それは可能ですromanNumeralDict.m[1000] = "New value"
brando
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.