英文:
How to declare a constant map in Golang?
问题
我正在尝试在Go语言中声明一个常量,但是它报错了。
这是我的代码:
const myMap = map[int]string{
1: "one",
2: "two",
3: "three",
}
这是错误信息:
map[int]string{...}(类型为map[int]string的值)不是常量
英文:
I am trying to declare to constant in Go, but it is throwing an error.
This is my code:
const myMap = map[int]string{
1: "one",
2: "two",
3: "three",
}
This is the error
map[int]string{…} (value of type map[int]string) is not constant
答案1
得分: 250
在Go语言中,不幸的是,map
不能被声明为const
。你可以使用var
关键字将其声明为普通变量,如下所示:
var myMap = map[int]string{
1: "one",
2: "two",
3: "three",
}
在函数内部,你可以使用短变量声明语法进行声明:
func main() {
myMap := map[int]string{
1: "one",
2: "two",
3: "three",
}
}
英文:
In Go, a map unfortunately cannot be const
. You can declare it as a regular variable like this with the var
keyword:
var myMap = map[int]string{
1: "one",
2: "two",
3: "three",
}
Inside a function, you may declare it with the short assignment syntax:
func main() {
myMap := map[int]string{
1: "one",
2: "two",
3: "three",
}
}
答案2
得分: 35
你可以用多种方式创建常量:
const myString = "hello"
const pi = 3.14 // 无类型常量
const life int = 42 // 有类型常量(只能用于整数)
你还可以创建枚举常量:
const (
First = 1
Second = 2
Third = 4
)
你不能创建映射和数组的常量,这在《Effective Go》中有所说明:
在Go中,常量就是常量。它们在编译时创建,即使在函数中定义为局部变量,也只能是数字、字符(符文)、字符串或布尔值。由于编译时的限制,定义常量的表达式必须是常量表达式,可以由编译器计算出结果。例如,1<<3是一个常量表达式,而math.Sin(math.Pi/4)不是,因为调用math.Sin的函数需要在运行时发生。
英文:
You can create constants in many different ways:
const myString = "hello"
const pi = 3.14 // untyped constant
const life int = 42 // typed constant (can use only with ints)
You can also create a enum constant:
const (
First = 1
Second = 2
Third = 4
)
You can not create constants of maps, arrays and it is written in effective go:
> Constants in Go are just that—constant. They are created at compile
> time, even when defined as locals in functions, and can only be
> numbers, characters (runes), strings or booleans. Because of the
> compile-time restriction, the expressions that define them must be
> constant expressions, evaluatable by the compiler. For instance, 1<<3
> is a constant expression, while math.Sin(math.Pi/4) is not because the
> function call to math.Sin needs to happen at run time.
答案3
得分: 18
你可以使用闭包来模拟一个映射:
package main
import (
"fmt"
)
// http://stackoverflow.com/a/27457144/10278
func romanNumeralDict() func(int) string {
// innerMap 被闭包捕获,返回的闭包函数中使用了 innerMap
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))
}
英文:
You may emulate a map with a closure:
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
得分: 4
根据Siu Ching Pong - Asuka Kenji的建议,以下是一个更合理的函数,它使用了地图类型,而没有在函数周围添加包装器:
// romanNumeralDict 返回 map[int]string 字典,由于返回值始终相同,它提供了伪常量的输出,可以以类似地图的方式引用。
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上尝试一下。
英文:
And as suggested above by Siu Ching Pong -Asuka Kenji with the function which in my opinion makes more sense and leaves you with the convenience of the map type without the function wrapper around:
// 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)
}
答案5
得分: 0
我知道这段代码看起来不太好看,但你可以使用匿名结构体和闭包来实现类似于常量映射的功能:
type MapGet[T any, V any] func(T) (V, bool)
var (
myMap = struct {
Get MapGet[int, string]
}{
Get: func(mp map[int]string) MapGet[int, string] {
return func(key int) (string, bool) {
v, found := mp[key]
return v, found
}
}(map[int]string{
1: "one",
2: "two",
3: "three",
}),
}
)
func main() {
v, _ := myMap.Get(1)
fmt.Println(v)
}
你可以在这里查看代码:https://goplay.tools/snippet/SrAMRsBOPn9
英文:
I know this is not the nicest looking code, but you can achieve somewhat of a constant map-like thing using anonymous structs and closures:
Voila!
type MapGet[T any, V any] func(T) (V, bool)
var (
myMap = struct {
Get MapGet[int, string]
}{
Get: func(mp map[int]string) MapGet[int, string] {
return func(key int) (string, bool) {
v, found := mp[key]
return v, found
}
}(map[int]string{
1: "one",
2: "two",
3: "three",
}),
}
)
func main() {
v, _ := myMap.Get(1)
fmt.Println(v)
}
答案6
得分: -5
如上所述,无法将地图定义为常量。但是,您可以声明一个全局变量,该变量是一个包含地图的结构体。
初始化的代码如下所示:
var romanNumeralDict = struct {
m map[int]string
}{m: map[int]string {
1000: "M",
900: "CM",
//在这里添加您的值
}}
func main() {
d := 1000
fmt.Printf("键(%d)的值为:%s", d, romanNumeralDict.m[1000])
}
英文:
As stated above to define a map as constant is not possible.
But you can declare a global variable which is a struct that contains a map.
The Initialization would look like this:
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])
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论