2016-08-21 8 views
0

init funcで初期化されたマップに値を割り当てようとしています。nilのエントリへの割り当て

しかし、パニックが発生します。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はありませんが、それを適切にin​​itがない:代わりにポインタでTestしてください。これだけNewTestを呼び出すことによってtestを得ることができ、ユーザを確実に

type test struct{ 
    collection map[uint64] Object 
} 

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

と意図したように、それが初期化されます:GOコミュニティは、自立NewType法の規則を確立しているように思えます。

+0

私はこのことを自分自身が分かっていないと信じられません。答えと余分な目をありがとう。 – Aidamina

1

あなたはinitメソッドのポインタ受信機を使用する必要があります。

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

をポインタがなければ、あなたはtestオブジェクトのコピーのためのマップを初期化しています。実際のtestオブジェクトは決して初期化されたマップを取得しません。

関連する問題