赋值给nil映射中的条目



我正在尝试给在init函数中初始化的map赋值。

但是恐慌发生了:赋值给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

函数将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,并且它将按预期初始化。

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

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

如果没有指针,您将初始化test对象副本的映射。实际的test对象永远不会得到一个初始化的map。

工作代码

最新更新