2017-05-22 18 views
5

私は別の構造体が埋め込まれた構造体を持っているとしましょう。私はChildを初期化するために行くとき、私は直接IDフィールドを初期化することはできませんGoで合成された構造体を初期化するにはどうすればよいですか?

type Base struct { 
    ID string 
} 

type Child struct { 
    Base 
    a int 
    b int 
} 

// unknown field 'ID' in struct literal of type Child 
child := Child{ ID: id, a: a, b: b } 

代わりにIDフィールドを個別に初期化する必要があります。

child := Child{ a: 23, b: 42 } 
child.ID = "foo" 

これはカプセル化に違反しているようです。 Childのユーザーは、IDフィールドについて異なるものがあることを知る必要があります。後で公開フィールドを埋め込み構造体に移動すると、初期化が中断される可能性があります。

は、私はすべての構造体のNewFoo()方法を書いて、誰もがあることを願って使用していますが、が埋め込まれているフィールドのいくつかを明らかにしない埋め込まれた構造体で安全リテラル構造体を使用する方法はありますでしょうか?ここで間違ったパターンを適用していますか?

+0

私は本当にそこにgithubの問題があるはずだと思う。私はgetter上の構文的な砂糖のように感じます([@CeriseLimónの回答](https://stackoverflow.com/questions/44123399/how-do-i-initialize-a-composed-struct-in-go/44123416? noredirect = 1#comment75266036_44123416))_really_も設定者に適用する必要があります。今やコードを醜くするだけでなく、クラスのユーザーがそれを使用するためにクラスの継承/階層に精通していることが必要です。 – KOGI

答えて

13

使用すると、単一の式の値を初期化するために、複合リテラルをネストされた:

child := Child{Base: Base{ID: id}, a: a, b: b} 

それはフィールドが埋め込まれた構造体から昇格されているという事実を隠すすることはできません。

+1

'child.ID'は' ID'が埋め込まれているのを隠していますが、イニシャライザは組み込まれていませんか?どのような奇妙な監視。初期化カプセル化が必要な場合、自分で 'New'関数を書く必要がありますか? – Schwern

+4

埋め込みフィールドのフィールド昇格は構文的な砂糖です。この機能はカプセル化を提供しません。 –

+0

カプセル化が行われないのはなぜですか? – Schwern

関連する問題