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