2016-08-21 8 views
0

Я пытаюсь назначить значения карте, инициализированной в функции init.назначение для записи на карте 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

ответ

2

Функция принимает Test как значение, поэтому он получает свою собственную копию этого. Все изменения на test Test исчезнут, когда функция вернется. Возьмите Test указателем вместо:

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

Примечание, хотя, структура Test экспортируется, метод init не является, следовательно, пользователь вашей библиотеки потенциально может создать Test, но не инициализировать его должным образом. Похоже, что идет сообщество установило условность в отдельно стоящей NewType методы:

type test struct{ 
    collection map[uint64] Object 
} 

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

Это обеспечивает пользователь может только получение test по телефону NewTest и он будет инициализирован, как предполагался.

+0

делает общий смысл, я не могу поверить, что я не понимаю, что это сам. Спасибо за ответ и дополнительную пару глаз. – Aidamina

1

Вы должны использовать приемник указателя для метода init:

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

Без указателя, вы инициализация карты для копии test объекта. Фактический объект test никогда не получает инициализированную карту.

Working Code