简体   繁体   English

Go地图的通用值类型

[英]Generic value type of Go map

I am working on a web app with Go language. 我正在使用Go语言开发Web应用程序。 The respond(writer, html, *params) function needs a list of parameters which can be used to render an HTML page. respond(writer, html, *params)函数需要一个可用于呈现HTML页面的参数列表。 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. 但是,最近我需要以{string, map[string][]string}的格式压缩一个值对,这显然使编译器崩溃了。 So I am wondering if there is any generic type I can utilize, ie map[string]GenericType . 所以我想知道是否可以使用任何泛型类型,即map[string]GenericType

Any thoughts is welcomed. 任何想法都欢迎。

So generally you store []string values for string keys. 因此,通常您会为string键存储[]string值。 Most of the time. 大多数时候。 And once in a while you'd like to store a map[string][]string value for a string key. 有时您想为string键存储map[string][]string值。

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: 仅保留一个映射并能够存储[]stringmap[string][]string类型的值,将需要您将值类型更改为interface{} ,但这将要求您每次使用Type断言访问params映射中的元素,例如:

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: 当然,您可以使用map[string]interface{}作为其基础类型创建一个新类型,并为最常见的值类型[]string添加Get()Set()方法,但我建议为该struct使用包装器struct参数,在多个字段中具有多个地图:

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. 您还可以将Get()Set()方法添加到Params ,以从最常用的Params.P映射中获取和设置元素。

Try it on the Go Playground . Go Playground上尝试一下。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM