以下の質問には複数の回答/テクニックがあります。
- golang構造体にデフォルト値を設定するにはどうすればよいですか?
- golangで構造体を初期化する方法
いくつか回答がありますが、さらに議論が必要です。
以下の質問には複数の回答/テクニックがあります。
いくつか回答がありますが、さらに議論が必要です。
回答:
考えられるアイデアの1つは、別個のコンストラクター関数を作成することです。
//Something is the structure we work with
type Something struct {
Text string
DefaultText string
}
// NewSomething create new instance of Something
func NewSomething(text string) Something {
something := Something{}
something.Text = text
something.DefaultText = "default text"
return something
}
NewSomething
やフィールドText
、をDefaultText
エクスポートできますが、構造体タイプはエクスポートしないでくださいsomething
。
reflect.New()
たとえばを介して)構造体をインスタンス化する場合、特別な名前のファクトリ関数について知ることはできません。その場合、言語自体が変更されない限り、インターフェース(ライブラリーがチェックできる)だけが機能すると思います。
メソッドに構造体を取得するよう強制します(コンストラクターの方法)。
優れた設計は、型をエクスポートされないようにすることですが、構造体/型を適切に初期化できるNewMyType()のようなエクスポートされたコンストラクター関数を提供します。また、具象型ではなくインターフェース型を返します。インターフェースには、他のユーザーがあなたの値で実行したいすべてのものが含まれている必要があります。そして具体的な型はもちろんそのインターフェースを実装する必要があります。
これは、型自体をエクスポートしないようにするだけで実行できます。関数NewSomethingとフィールドTextおよびDefaultTextをエクスポートできますが、構造体タイプはエクスポートしないでください。
独自のモジュール用にカスタマイズするもう1つの方法は、Config構造体を使用してデフォルト値を設定することです(リンクのオプション5)。
Victor Zamanianからの回答のオプション1の1つの問題は、型がエクスポートされない場合、パッケージのユーザーはそれを関数パラメーターなどの型として宣言できないことです。これを回避する1つの方法は、 struct eg
package candidate
// Exporting interface instead of struct
type Candidate interface {}
// Struct is not exported
type candidate struct {
Name string
Votes uint32 // Defaults to 0
}
// We are forced to call the constructor to get an instance of candidate
func New(name string) Candidate {
return candidate{name, 0} // enforce the default value here
}
これにより、エクスポートされたCandidateインターフェイスを使用して関数パラメーターの型を宣言できます。このソリューションからわかる唯一の欠点は、すべてのメソッドをインターフェイス定義で宣言する必要があることですが、いずれにしてもそれは良い習慣であると主張できます。
Votes unit32
おそらくVotes uint32
これをタグで行う方法があり、複数のデフォルトを使用できます。
次の構造体があり、2つのデフォルトタグdefault0およびdefault1があるとします。
type A struct {
I int `default0:"3" default1:"42"`
S string `default0:"Some String..." default1:"Some Other String..."`
}
これで、デフォルトを設定することができます。
func main() {
ptr := &A{}
Set(ptr, "default0")
fmt.Printf("ptr.I=%d ptr.S=%s\n", ptr.I, ptr.S)
// ptr.I=3 ptr.S=Some String...
Set(ptr, "default1")
fmt.Printf("ptr.I=%d ptr.S=%s\n", ptr.I, ptr.S)
// ptr.I=42 ptr.S=Some Other String...
}
ここだ遊び場での完全なプログラムを。
スライスやマップなど、より複雑な例に興味がある場合は、creasty / defaultseを見てください。
https://golang.org/doc/effective_go.html#composite_literalsから:
パッケージosから派生したこの例のように、ゼロの値では不十分で、初期化コンストラクターが必要な場合があります。
func NewFile(fd int, name string) *File {
if fd < 0 {
return nil
}
f := new(File)
f.fd = fd
f.name = name
f.dirinfo = nil
f.nepipe = 0
return f
}
type Config struct {
AWSRegion string `default:"us-west-2"`
}