254

私は構造体を持っており、適切なデフォルト値で初期化したいと考えています。

通常、ここで行うことはコンストラクターを使用することですが、go は従来の意味で実際には OOP ではないため、これらは真のオブジェクトではなく、コンストラクターがありません。

init メソッドに気付きましたが、それはパッケージ レベルです。構造体レベルで使用できる類似のものは他にありますか?

そうでない場合、Goでこの種のことに対して受け入れられているベストプラクティスは何ですか?

4

10 に答える 10

258

ゼロ値が適切なデフォルト値を作成できない場合、または構造体の初期化に何らかのパラメーターが必要な場合のために、コンストラクターに相当するものがいくつかあります。

次のような構造体があるとします。

type Thing struct {
    Name  string
    Num   int
}

次に、ゼロ値が適切でない場合は、通常NewThing、ポインターを返す関数を使用してインスタンスを作成します。

func NewThing(someParameter string) *Thing {
    p := new(Thing)
    p.Name = someParameter
    p.Num = 33 // <- a very sensible default value
    return p
}

構造体が十分に単純な場合は、次の圧縮された構造体を使用できます。

func NewThing(someParameter string) *Thing {
    return &Thing{someParameter, 33}
}

ポインターを返したくない場合は、次のmakeThing代わりに関数を呼び出すことをお勧めしNewThingます。

func makeThing(name string) Thing {
    return Thing{name, 33}
}

参考:Effective Go での new による割り当て

于 2013-08-08T12:10:16.137 に答える
164

実際には、受け入れられているベスト プラクティスが 2 つあります。

  1. 構造体のゼロ値を適切なデフォルトにします。(これは、「伝統的な」おっとから来ているほとんどの人にとって奇妙に見えますが、多くの場合機能し、非常に便利です)。
  2. 関数を提供するfunc New() YourTypか、パッケージ関数などにそのようなタイプがいくつかある場合func NewYourType1() YourType1

タイプのゼロ値が使用可能かどうかを文書化します (その場合、関数のいずれかで設定する必要がありNew...ます。(「伝統主義者」のおっと: ドキュメントを読まない人は使用できません)未定義の状態でオブジェクトを作成できない場合でも、適切に型を作成してください。)

于 2013-08-08T12:14:23.763 に答える
12

Go にはデフォルトのコンストラクターはありませんが、任意の型のメソッドを宣言できます。「Init」と呼ばれるメソッドを宣言することを習慣にすることができます。これがベスト プラクティスにどのように関係するかはわかりませんが、明確さを失わずに名前を短くするのに役立ちます。

package main

import "fmt"

type Thing struct {
    Name string
    Num int
}

func (t *Thing) Init(name string, num int) {
    t.Name = name
    t.Num = num
}

func main() {
    t := new(Thing)
    t.Init("Hello", 5)
    fmt.Printf("%s: %d\n", t.Name, t.Num)
}

結果は次のとおりです。

Hello: 5
于 2014-09-30T16:01:03.363 に答える
4

別の方法は;

package person

type Person struct {
    Name string
    Old  int
}

func New(name string, old int) *Person {
    // set only specific field value with field key
    return &Person{
        Name: name,
    }
}
于 2015-11-26T20:14:35.543 に答える