web-dev-qa-db-ja.com

Golangの基本構造とnew()キーワード

私はgolangを学んでいたのですが、構造について説明している章を読んでいると、構造を初期化するさまざまな方法に出会いました。

p1 := passport{}
var p2 passport
p3 := passport{
    Photo: make([]byte, 0, 0),
    Name: "Scott",
    Surname: "Adam",
    DateOfBirth: "Some time",
}

fmt.Printf("%s\n%s\n%s\n", p1, p2, p3)

これらは、構造体の値を

{ } { } { Scott Adam Some time}、以下のコードは参照であるため、アンパサンド付きで出力されます。

pointerp1 := &p3
fmt.Printf("%s", pointerp1)
pointerp2 := new(passport)
pointerp2.Name = "Anotherscott"
fmt.Printf("%s", pointerp2)

&{ Scott Adam Some time}&{ Anotherscott }

疑いを寄せてください。

  1. 使用法pointerp1 := &p3で、pointerp1は、実際のデータを保持するp3への参照変数です。同様に、pointerp2のデータを保持する実際の変数は何でしょうか?

  2. これらの異なるタイプの初期化を使用するのに最適なシナリオは何ですか?

29
scott
  1. まだデータを保持する変数があります。 *pointerp2を使用してポインターを逆参照し、それを変数(p2 := pointerp2)に割り当てることもできますが、この変数はデータのコピーになります。つまり、一方を変更してももう一方には影響しません( http://play.golang.org/p/9yRYbyvG8q )。

  2. newは、特に構造体に関してはあまり人気がありません。その目的(ヒント:最初に来た)とユースケースの良い議論は https://softwareengineering.stackexchange.com/a/216582 にあります。

編集:また、p1は実際にはp3と異なる種類の初期化ではありませんが、タイプのフィールドのいずれかに値を割り当てる代わりに、ゼロ値に初期化されます(""stringnil for []byte)。省略されたフィールドでも同じことが起こります。

p4 := passport{
    Name: "Scott",
    Surname: "Adam",
}

この場合、p4.Photop4.DateOfBirthはまだゼロ値です(それぞれnil"")。 passport{}は、すべてのフィールドが省略されている場合の1つです。

3
Igor Dubinskiy

新しいキーワードは、基本的に必要なタイプのインスタンスを作成するだけです。ただし、型の単純な宣言を返す代わりに、それを参照し、プログラムプロセスヒープ内のその型の実際のメモリアドレスを返します。

2
Remario