How to declare a constant map in Golang?

Go

Go Problem Overview


I am trying to declare to constant in Go, but it is throwing an error. Could anyone please help me with the syntax of declaring a constant in Go?

This is my code:

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

This is the error

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

Go Solutions


Solution 1 - Go

Your syntax is incorrect. To make a literal map (as a pseudo-constant), you can do:

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

Inside a func you can declare it like:

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

And in Go there is no such thing as a constant map. More information can be found here.

Try it out on the Go playground.

Solution 2 - Go

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.

Solution 3 - Go

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

Try it on the Go playground

Solution 4 - Go

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

Try this at play.golang.org.

Solution 5 - Go

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionsamolView Question on Stackoverflow
Solution 1 - GosquiguyView Answer on Stackoverflow
Solution 2 - GoSalvador DaliView Answer on Stackoverflow
Solution 3 - GooleberView Answer on Stackoverflow
Solution 4 - GoDenis VolinView Answer on Stackoverflow
Solution 5 - GoindeView Answer on Stackoverflow