【问题标题】:Is there autovivification for Go?Go 有自动生存功能吗?
【发布时间】:2016-12-30 16:11:14
【问题描述】:

Go 有 autovivification 吗?

正如@JimB 正确注意到的那样,我的定义并不那么严格。关于我的目标:在 Python 中,我们有一个非常优雅的 “仿真” 用于自动生存:

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

Go 有类似的解决方案吗?

【问题讨论】:

  • Go 是静态类型和编译的。你不能真的有一个“未定义的引用”,如果有一个不应该有的 nil 引用,那是你的程序中的一个错误。
  • 这也适用于 C++,并且有可能。我错了吗?
  • 我想这取决于你的定义。我不会将 C++ 可以执行的定义称为“自动激活”,它只是在比较或模拟行为时列出。如果键不存在,Go 也可以从映射中返回零值,但仍需要定义值。
  • 谢谢,很好。我只是喜欢class Tree(dict): def __missing__(self, key)... 的 Python 方式,我认为有一些类似的优雅解决方案。我扩展了我的问题。

标签: go autovivification


【解决方案1】:

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

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"]

由于带有数值返回的映射将针对缺少的条目返回 0,因此 Go 允许您对不存在的键使用递增和递减运算符:

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

【讨论】:

    【解决方案2】:

    还扩展了 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
    

    【讨论】:

      猜你喜欢
      • 2011-08-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-22
      • 1970-01-01
      • 1970-01-01
      • 2010-10-30
      相关资源
      最近更新 更多