如何声明常数图


125

我试图在Go中声明为constant,但是它抛出一个错误。有人可以在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 {

Answers:


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

在a中,func您可以这样声明:

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

在Go中,没有常量映射之类的东西。可以在此处找到更多信息。

在Go游乐场尝试一下。


1
non-declaration statement outside function body实际上这会在编译时抛出一个。怎么会?
alediaferia 2014年

@AlessandroDiaferia我没有得到这样的错误。您如何使用它?
squiguy 2014年

7
var romanNumeralDict map[int]string = map[int]string{...}在这种情况下,请尝试@AlessandroDiaferia 。
B扫描

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您能解释一下为什么我的答案不相关吗?他问如何创造东西,我告诉他这是不可能的。解释了可行的方法,并从文档中引出了为什么不可能做他想做的事情。
萨尔瓦多·达利

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 2014年

1
实际上,这是一个可能的解决方案。但是,由于作者没有解释任何内容(而是将所有内容放在一个怪异的测试用例中),因此答案似乎不正确。逻辑是:(1)创建一个匿名函数(2)匿名函数封装map(3)匿名函数返回“一个接受int并返回字符串的函数”(4)返回的函数执行int-> string使用map(5)进行映射。立即执行匿名函数,并将返回的函数分配给变量。该变量可以像函数一样使用,其效果就像地图。
小清庞-明日香贤治

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 18'Jan
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.