상수 맵 선언 방법


126

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 {

답변:


154

구문이 올바르지 않습니다. 리터럴 맵 (의사 상수)을 만들려면 다음을 수행 할 수 있습니다.

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실제로 컴파일 시간에 발생합니다. 어째서?
alediaferia 2014

@AlessandroDiaferia 그런 오류가 발생하지 않습니다. 어떻게 사용하고 있습니까?
squiguy

7
@AlessandroDiaferia var romanNumeralDict map[int]string = map[int]string{...}는 그런 경우에 시도 합니다.
B-Scan

4
@alediaferia :=함수 외부에서 사용하면 해당 오류가 발생 합니다.
제프리 마르티네즈

1
"의사 상수"란 무엇입니까?
Garrett

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

5
@ jzer7 내 대답이 무관 한 이유를 설명해 주시겠습니까? 그는 무언가를 만드는 방법을 물었고 나는 이것이 불가능하다고 말했습니다. 무엇이 가능한지 설명하고 그가 원하는 것을 정확히 할 수없는 이유를 문서에서 인용했습니다.
Salvador Dali

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

Go 놀이터에서 사용해보세요


4
(TestMostSoldRecommender?)
twotwotwo

1
실제로 가능한 해결책입니다. 그러나 저자가 아무것도 설명하지 않았기 때문에 (이상한 이름의 테스트 케이스 안에 모든 것을 넣었 기 때문에) 답이 틀린 것 같습니다. 논리는 다음과 같습니다. (1) 익명 함수 만들기 (2) 익명 함수는 다음을 캡슐화합니다. map(3) 익명 함수는 "int를 받아들이고 문자열을 반환하는 함수"를 반환합니다. (4) 반환 된 함수는 int-> 문자열을 수행합니다. 사용하여 매핑 map즉시 익명 함수를 실행하고 변수에 반환 된 기능을 할당 (5). 이 변수는 함수처럼 사용할 수 있으며 효과는 맵과 같습니다.
Siu Ching Pong -Asuka Kenji- 2015

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.