Go 構造体のインスタンス化と代入を例を挙げて説明する

藏色散人
リリース: 2021-11-19 16:20:41
転載
2989 人が閲覧しました

Golang struct のさまざまなインスタンス化と代入の方法 (値の転送、ポインターによる場合もあります) は混乱を招くため、整理して全体を理解することにしました。 。

まず構造を定義し、以下のコードで説明します。

package mainimport "fmt"type Person struct {
    Name string
    Age int
    Descprtion string}
ログイン後にコピー

例 1

p は、最も一般的な方法で構造体をインスタンス化し、変数 p は Person 構造体を取得します。

p := Person{}
p.Name = "小明"

fmt.Printf("p:%+v 变量地址:%p\n", p, &p)
fmt.Println("===========")

// result:
// p:{Name:小明 Age:0 Descprtion:} 变量地址:0xc000078480
// ===========
ログイン後にコピー

例 2

変数 p1 は p によって代入されます。Golang 言語は value transfer なので、代入後、 p1 は影響しません p;

最初の出力からも、Golang の代入には PHP 変数の代入のような copy on write メカニズムがないことがわかります。

p1 := p
fmt.Printf("p1:%+v 变量地址:%p\n", p1, &p1) // 不存在写时复制
p1.Name = "小明p1"
fmt.Printf("p:%+v 变量地址:%p\n", p, &p)
fmt.Printf("p1:%+v 变量地址:%p\n", p1, &p1)
fmt.Println("===========")

// result:
// p1:{Name:小明 Age:0 Descprtion:} 变量地址:0xc0000784e0
// p:{Name:小明 Age:0 Descprtion:} 变量地址:0xc000078480
// p1:{Name:小明p1 Age:0 Descprtion:} 变量地址:0xc0000784e0
// ===========
ログイン後にコピー

例 3

アドレス演算子を使用して、p のアドレスを p2 に割り当てます。変数 p2 は、p を指すアドレスを格納するポインタです。 。 p2 が構造内の要素 Name を変更すると、p を介してアクセスされる構造に対応する値もそれに応じて変更されます。

p2 := &p // 等同于 var p2 *Person = &p
fmt.Printf("p2:%+v 指针变量指向地址(变量值):%p 变量地址:%p\n", p2, p2, &p2)
p2.Name = "小明p2"
fmt.Printf("p1:%+v 变量地址:%p\n", p, &p)
fmt.Printf("p2:%+v 指针变量指向地址(变量值):%p 变量地址:%p\n", p2, p2, &p2)
fmt.Println("===========")

// result:
// p2:&{Name:小明 Age:0 Descprtion:} 指针变量指向地址(变量值):0xc000078480 变量地址:0xc000006030
// p1:{Name:小明p2 Age:0 Descprtion:} 变量地址:0xc000078480
// p2:&{Name:小明p2 Age:0 Descprtion:} 指针变量指向地址(变量值):0xc000078480 变量地址:0xc000006030
// ===========
ログイン後にコピー

例 4

変数 p3 は new(person) から取得されます。 new はメモリの一部を開き、メモリ アドレスを p3 に返します。つまり、p3 はこのメモリへのポインタです。

p3 は構造体へのポインタです。この構造体を操作するには、

p3.Age = 3*p3 = Person{Name: "Xiao Ming p3" という 2 つの方法があります。 }, 2 番目のメソッドの後に操作が実行された場合、最初のメソッドでの構造の変更は上書きされます。

p3 はポインタであるため、p3 が p5 に割り当てられると、p5 もこのメモリ アドレスを指します。

p3 := new(Person)
fmt.Printf("p3:%+v 指针变量指向地址(变量值):%p 变量地址:%p\n", p3, p3, &p3)
p3.Age = 3 // 等同于 (*p3).Age = 3
fmt.Println("================ 操作 Age ================")
fmt.Printf("p3:%+v 指针变量指向地址(变量值):%p 变量地址:%p\n", p3, p3, &p3)
*p3 = Person{
    Name: "小明p3",
}
fmt.Println("================ 操作 Name ================")
fmt.Printf("p3:%+v 指针变量指向地址(变量值):%p 变量地址:%p\n", p3, p3, &p3)
p5 := p3
fmt.Println("================ p5 := p3 ================")
fmt.Printf("p3:%+v 指针变量指向地址(变量值):%p 变量地址:%p\n", p3, p3, &p3)
fmt.Printf("p5:%+v 指针变量指向地址(变量值):%p 变量地址:%p\n", p5, p5, &p5)
p3.Name = "小明p3修改"
fmt.Println("================ p3 修改 ================")
fmt.Printf("p3:%+v 指针变量指向地址(变量值):%p 变量地址:%p\n", p3, p3, &p3)
fmt.Printf("p5:%+v 指针变量指向地址(变量值):%p 变量地址:%p\n", p5, p5, &p5)
fmt.Println("===========")

// result:
// p3:&{Name: Age:0 Descprtion:} 指针变量指向地址(变量值):0xc000078630 变量地址:0xc000006038
// ================ 操作 Age ================
// p3:&{Name: Age:3 Descprtion:} 指针变量指向地址(变量值):0xc000078630 变量地址:0xc000006038
// ================ 操作 Name ================
// p3:&{Name:小明p3 Age:0 Descprtion:} 指针变量指向地址(变量值):0xc000078630 变量地址:0xc000006038
// ================ p5 := p3 ================
// p5:&{Name:小明p3 Age:0 Descprtion:} 指针变量指向地址(变量值):0xc000078630 变量地址:0xc000006040
// ================ p3 修改 ================
// p3:&{Name:小明p3修改 Age:0 Descprtion:} 指针变量指向地址(变量值):0xc000078630 变量地址:0xc000006038
// p5:&{Name:小明p3修改 Age:0 Descprtion:} 指针变量指向地址(变量值):0xc000078630 变量地址:0xc000006040
// ===========
ログイン後にコピー

例 5

p4 のインスタンス化メソッドもポインターを取得します。このインスタンス化メソッドは p3 のインスタンス化と同じですが、p4 は形式の方が一般的に使用されます。

p4 := &Person{
    Name: "小明p4",}fmt.Printf("%+v %p\n", p4, &p4)// result:// &{Name:小明p4 Age:0 Descprtion:} 0xc000006048
ログイン後にコピー

完全なコードを添付します:

package mainimport "fmt"type Person struct {
    Name string
    Age int
    Descprtion string}func main() {
    p := Person{}
    p.Name = "小明"

    fmt.Printf("p:%+v 变量地址:%p\n", p, &p)
    fmt.Println("===========")

    p1 := p
    fmt.Printf("p1:%+v 变量地址:%p\n", p1, &p1) // 不存在写时复制
    p1.Name = "小明p1"
    fmt.Printf("p:%+v 变量地址:%p\n", p, &p)
    fmt.Printf("p1:%+v 变量地址:%p\n", p1, &p1)
    fmt.Println("===========")

    p2 := &p
    fmt.Printf("p2:%+v 指针变量指向地址(变量值):%p 变量地址:%p\n", p2, p2, &p2)
    p2.Name = "小明p2"
    fmt.Printf("p1:%+v 变量地址:%p\n", p, &p)
    fmt.Printf("p2:%+v 指针变量指向地址(变量值):%p 变量地址:%p\n", p2, p2, &p2)
    fmt.Println("===========")

    p3 := new(Person)
    fmt.Printf("p3:%+v 指针变量指向地址(变量值):%p 变量地址:%p\n", p3, p3, &p3)
    p3.Age = 3 // 等同于 (*p3).Age = 3
    fmt.Println("================ 操作 Age ================")
    fmt.Printf("p3:%+v 指针变量指向地址(变量值):%p 变量地址:%p\n", p3, p3, &p3)
    *p3 = Person{
        Name: "小明p3",
    }
    fmt.Println("================ 操作 Name ================")
    fmt.Printf("p3:%+v 指针变量指向地址(变量值):%p 变量地址:%p\n", p3, p3, &p3)
    p5 := p3
    fmt.Println("================ p5 := p3 ================")
    fmt.Printf("p3:%+v 指针变量指向地址(变量值):%p 变量地址:%p\n", p3, p3, &p3)
    fmt.Printf("p5:%+v 指针变量指向地址(变量值):%p 变量地址:%p\n", p5, p5, &p5)
    p3.Name = "小明p3修改"
    fmt.Println("================ p3 修改 ================")
    fmt.Printf("p3:%+v 指针变量指向地址(变量值):%p 变量地址:%p\n", p3, p3, &p3)
    fmt.Printf("p5:%+v 指针变量指向地址(变量值):%p 变量地址:%p\n", p5, p5, &p5)
    fmt.Println("===========")

    p4 := &Person{
        Name: "小明p4",
    }
    fmt.Printf("%+v %p\n", p4, &p4)}
ログイン後にコピー
終了!

以上がGo 構造体のインスタンス化と代入を例を挙げて説明するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:learnku.com
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート