ホームページ >バックエンド開発 >Golang >Go 構造体のインスタンス化と代入を例を挙げて説明する

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

藏色散人
藏色散人転載
2021-11-19 16:19:373023ブラウズ

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 までご連絡ください。