Go语言中是否有自动创建嵌套结构的功能(autovivification)?

huangapple go评论73阅读模式
英文:

Is there autovivification for Go?

问题

在Go语言中是否有自动创建嵌套结构的功能(autovivification)?

正如@JimB正确指出的那样,我的定义并不那么严格。关于我的目标:在Python中,我们有一种非常优雅的“模拟”自动创建嵌套结构的方法:

type Path map[string]interface{}

func (p Path) Get(key string) interface{} {
    if val, ok := p[key]; ok {
        return val
    }
    p[key] = make(Path)
    return p[key]
}

在Go语言中是否有类似的解决方案?

英文:

Is there autovivification for Go?

As @JimB correctly noticed, my definition is not that strict. About my goal: In Python we have a very elegant "emulation" for an autovivification:

class Path(dict):
	def __missing__(self, key):
			value = self[key] = type(self)()
			return value

Is there a similar solution for Go?

答案1

得分: 4

如果键不存在或地图为nil,Go的映射将返回该类型的零值。

https://play.golang.org/p/sBEiXGfC1c

var sliceMap map[string][]string

// slice是一个nil []string
slice := sliceMap["不存在的键"]


var stringMap map[string]string

// s是一个空字符串
s := stringMap["不存在的键"]

由于具有数值值的映射在缺少条目时返回0,Go允许您在不存在的键上使用递增和递减运算符:

counters := map[string]int{}
counters["one"]++

英文:

Go maps will return a zero value for the type if the key doesn't exist, or the map is nil

https://play.golang.org/p/sBEiXGfC1c

var sliceMap map[string][]string

// slice is a nil []string
slice := sliceMap["does not exist"]


var stringMap map[string]string

// s is an empty string
s := stringMap["does not exist"]

Since a map with numeric values return will return 0 for missing entries, Go lets you use the increment and decrement operators on non-existent keys:

counters := map[string]int{}
counters["one"]++

答案2

得分: 1

此外,扩展JimB的答案,通过使用mapinterface{}type assertion的组合,您可以动态创建任何复杂的结构:

type Obj map[interface{}]interface{}

func main() {
    var o Obj

    o = Obj{
        "Name": "Bob",
        "Age":  23,
        3:      3.14,
    }
    fmt.Printf("%+v\n", o)

    o["Address"] = Obj{"Country": "USA", "State": "Ohio"}
    fmt.Printf("%+v\n", o)

    o["Address"].(Obj)["City"] = "Columbus"
    fmt.Printf("%+v\n", o)

    fmt.Printf("City = %v\n", o["Address"].(Obj)["City"])
}

输出结果(在Go Playground上尝试):

map[Name:Bob Age:23 3:3.14]
map[Age:23 3:3.14 Address:map[Country:USA State:Ohio] Name:Bob]
map[3:3.14 Address:map[Country:USA State:Ohio City:Columbus] Name:Bob Age:23]
City = Columbus

  [1]: https://golang.org/ref/spec#Type_assertions
  [2]: https://play.golang.org/p/Q30UxRJ5H1
英文:

Also extending JimB's answer, with the combination of map, interface{} and type assertion, you can dynamically create any complex structures:

type Obj map[interface{}]interface{}

func main() {
	var o Obj

	o = Obj{
		"Name": "Bob",
		"Age":  23,
		3:      3.14,
	}
	fmt.Printf("%+v\n", o)

	o["Address"] = Obj{"Country": "USA", "State": "Ohio"}
	fmt.Printf("%+v\n", o)

	o["Address"].(Obj)["City"] = "Columbus"
	fmt.Printf("%+v\n", o)

	fmt.Printf("City = %v\n", o["Address"].(Obj)["City"])
}

Output (try it on the Go Playground):

map[Name:Bob Age:23 3:3.14]
map[Age:23 3:3.14 Address:map[Country:USA State:Ohio] Name:Bob]
map[3:3.14 Address:map[Country:USA State:Ohio City:Columbus] Name:Bob Age:23]
City = Columbus

huangapple
  • 本文由 发表于 2016年12月31日 00:11:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/41399222.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定