Go地图的通用值类型

I am working on a web app with Go language. The respond(writer, html, *params) function needs a list of parameters which can be used to render an HTML page. I came up with a map as this which works fine:

&map[string][]string

However, recently I need to squeeze in a value pair in the format of {string, map[string][]string} which obviously blew up the compiler. So I am wondering if there is any generic type I can utilize, i.e. map[string]GenericType.

Any thoughts is welcomed.

So generally you store []string values for string keys. Most of the time. And once in a while you'd like to store a map[string][]string value for a string key.

First, drop the pointer from the map type: maps are already small descriptors, you can pass maps which will pass a copy of the descriptor and not the whole content, and if you add a new key-value pair to the copy, you will see that in the original. Passing a map by value is efficient and has the desired effect / working.

To be precise: map types are actually pointers to a map descriptor under the hood, but this is an implementation detail, you don't need to know this to use / work with maps. Only thing that matters is you can pass around map values efficiently.

Keeping only one map and being able to store values of both type []string and map[string][]string would require you to change the value type to interface{}, but then this would require you to use Type assertion every time you access an element in the params map, something like:

params := map[string]interface{}{}
params["a"] = []string{"b", "c"}

if list, ok := params["a"].([]string); ok {
    fmt.Println(list)
}

Of course you could create a new type with map[string]interface{} being its underlying type, and add Get() and Set() methods for the most common value type []string, but instead I recommend a wrapper struct for the params, with multiple maps in multiple fields:

type Params struct {
    P map[string][]string
    M map[string]map[string][]string
}

Your code may use the map whichever has the value type that suits the value to be stored, for example:

params2 := Params{map[string][]string{}, map[string]map[string][]string{}}
params2.P["a"] = []string{"b", "c"}

params2.M["B"] = map[string][]string{
    "x": []string{"X", "Y"},
}

fmt.Println(params2.P["a"])
fmt.Println(params2.M["B"])

You may also add Get() and Set() methods to Params that get and set elements from the most frequently used Params.P map.

Try it on the Go Playground.