go語言基礎結構體傳參

 閱讀大約需要1分鐘

go語言基礎結構體傳參

使用struct關鍵字可以定義一個結構體,結構體中的成員稱為結構體的字段或屬性。

type Person1 struct {
	Name string
	Age  int
}

直接定義變量,這個使用方式並沒有為字段賦初始值,因此所有字段都會被自動賦予自已類型的零值,比如Name的值為空字符串"",Age的值為0。

var p1 Person1
fmt.Println(p1)

結構體與數組一樣,都是值傳遞,比如當把數組或結構體作為實參傳給函數的形參時,會復制一個副本,所以為了提高性能,一般不會把數組直接傳遞給函數,而是使用切片(引用類型)代替,而把結構體傳給函數時,可以使用指針結構體。

指針結構體,即一個指向結構體的指針,聲明結構體變量時,在結構體類型前加*號,便聲明一個指向結構體的指針

var p2 *Person1
p2.Name="Hello"

使用Go內置new()函數,可以分配內存來初始化結構休,並返回分配的內存指針,因為已經初始化了,所以可以直接訪問字段。

p3:=new(Person1)
p3.Name="Hello"
fmt.Println(*p3)

如果將結構體傳遞給函數,只是複制結構體的副本,如果在函數內修改結構體字段值,外面的結構體並不會受影響,而如果將結構體指針傳給函數,則在函數中使用指針對結構體所做的修改,都會影響到指針指向的結構體。

package main

import "fmt"

type Person1 struct {
	Name string
	Age  int
}

func main() {
	var p1 Person1
	fmt.Println(p1)
	//var p2 *Person1
	//p2.Name="Hello" //空指針 未初始化 p2為nil
	p3:=new(Person1)
	p3.Name="Hello"
	fmt.Println(*p3)

	p := Person1{Name: "John", Age: 18}
	fmt.Printf("before change pointer address %p\n", &p)
	noModify(p)
	fmt.Println(p.Age, p.Name)
	modifyPerson(&p)
	fmt.Println(p.Age, p.Name)
}

func noModify(p Person1) {
	fmt.Printf("noModify's pointer %p\n", &p)
	p.Name = "bruce"
	p.Age = 19
}

func modifyPerson(p *Person1) {
	fmt.Printf("modifyPerson's pointer %p\n", p)
	fmt.Printf("modifyPerson p's pointer %p\n", &p)
	p.Name = "bruce"
	p.Age = 19
}

運行結果如下:

{ 0}
{Hello 0}
before change pointer address 0xc00000c060
noModify's pointer 0xc00000c078
18 John
modifyPerson's pointer 0xc00000c060
modifyPerson p's pointer 0xc00000e030
19 bruce

根據運行結果可以看出結構體傳參前後的內存地址是不同的,結構體指針傳遞給函數,指針結構體中的值就是實參結構體的地址,所以改變 形參的值實參的值也會跟著改變。