英文:
assignment to entry in nil map
问题
我正在尝试为在init函数中初始化的map分配值。
但是发生了panic:
assignment to entry in nil map
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
英文:
I am trying to assign values to a map that is initialized in the init func.
But panic occurs:
assignment to entry in nil map
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{}
}
答案1
得分: 3
该函数以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
}
func NewTest() *test {
return &test{
collection: make(map[uint64] Object),
}
}
这样确保用户只能通过调用NewTest
来获取一个test
,并且它将按预期进行初始化。
英文:
The function takes Test
as value, so it gets its own copy of it. All changes to test Test
will be gone when the function returns. Take Test
by pointer instead:
func (test *Test) init(){
test.collection = make(map[uint64] Object)
}
Note though, the struct Test
is exported, the method init
is not, therefore a user of your library could potentially create a Test
but not init it properly. It seems like the go community has established the convention of a freestanding NewType
method:
type test struct{
collection map[uint64] Object
}
function NewTest() *test {
return &test{
collection: make(map[uint64] Object),
}
}
This ensures a user can only obtain a test
by calling NewTest
and it will be initialized as intended.
答案2
得分: 1
你应该为init
方法使用指针接收器:
func (test *Test) init() { // 使用指向test的指针
test.collection = make(map[uint64]Object)
}
如果没有使用指针,你将为test
对象的副本初始化一个映射。实际的test
对象永远不会得到一个初始化的映射。
英文:
You should use a pointer receiver for the init
method:
func (test *Test) init() { // use a pointer to test
test.collection = make(map[uint64] Object)
}
Without a pointer, you are initializing a map for a copy of the test
object. The actual test
object never gets an initialized map.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论