【问题标题】:assignment to entry in nil map分配给 nil 映射中的条目
【发布时间】:2016-08-21 12:34:09
【问题描述】:

我正在尝试将值分配给在 init func 中初始化的映射。

但是发生了恐慌: 分配给 nil 映射中的条目

package main

type Object interface { 
}

type ObjectImpl struct {
}

type Test struct{
    collection map[uint64] Object
}

func (test Test) init(){
    test.collection = make(map[uint64] Object)
}

func main() {
    test := &Test{}
    test.init()
    test.collection[1]=&ObjectImpl{}
}

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

【问题讨论】:

    标签: dictionary go instantiation


    【解决方案1】:

    该函数将Test 作为值,因此它得到它自己的副本。当函数返回时,对test Test 的所有更改都将消失。用指针取Test

    func (test *Test) init(){
        test.collection = make(map[uint64] Object)
    }
    

    请注意,结构 Test 已导出,init 方法未导出,因此您的库的用户可能会创建 Test 但无法正确初始化它。似乎 Go 社区已经建立了独立的 NewType 方法的约定:

    type test struct{
        collection map[uint64] Object
    }
    
    function NewTest() *test {
        return &test{
            collection: make(map[uint64] Object),
        }
    }
    

    这确保用户只能通过调用NewTest 获得test,并且它将按预期进行初始化。

    【讨论】:

    • 完全有道理,我不敢相信我自己没有意识到这一点。感谢您的回答和额外的一双眼睛。
    【解决方案2】:

    您应该为init 方法使用指针接收器:

    func (test *Test) init() {  // use a pointer to test
        test.collection = make(map[uint64] Object)
    }
    

    如果没有指针,您正在为 test 对象的副本初始化映射。实际的 test 对象永远不会获得初始化的映射。

    Working Code

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-01-31
      • 2013-02-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多