在go語言中,值傳遞和引用傳遞的思想貫穿著切片和結構體。
在陣列切片中,值傳遞
就是 copy
,當改變這個值得時候,原值是不會變的。原因是值傳遞的值 只是對初始值的一個 copy
。
在陣列切片中,引用傳遞
就是 view
, 此時傳遞過去的是這個陣列在底層儲存的地址,你改變這個值就相當於對原始值操作,所以會改變原始值。具體可以看這篇文章:部落格:你知道 go 切片的 copy 和 view 嗎
結構體的值傳遞和引用傳遞
結構體的值傳遞和引用傳遞 類似於陣列切片的值得傳遞方式。
值傳遞
type person struct {
name string
age int
gender string
}
// 方法定義
func (p person) setName(name string) {
p.name = name
fmt.Println("person name is:", p.name)
}
func (p *person) describe() {
fmt.Printf("我叫 %v, 我今年 %v 了", p.name, p.age)
}
func main() {
p := person{"Tom", 22, "man"}
// 修改name的值
p.setName("jury")
p.describe()
}
如上,我們在 setName
這個函式的接受者 是 p person
。 此時,就相當於把person{"Tom", 22, "man"}
拷貝一份傳遞過去。如下圖
執行結果為:
person name is: jury
我叫 tom, 我今年 25 了
我們改的僅僅是copy 的那份資料的值
引用傳遞
引用傳遞就是將該值在記憶體中的儲存地址傳遞過去。
type person struct {
name string
age int
gender string
}
// 方法定義
func (p *person) setName(name string) {
p.name = name
fmt.Println("person name is:", p.name)
}
func (p *person) describe() {
fmt.Printf("我叫 %v, 我今年 %v 了", p.name, p.age)
}
func main() {
p := person{"Tom", 22, "man"}
// 修改name的值
p.setName("jury")
p.describe()
}
我們在 setName
這個函式的接受者 是 p *person
。 此時,就相當於把person{"Tom", 22, "man"}
儲存地址傳遞過去。如下圖
所以輸出結果就為:
person name is: jury
我叫 jury, 我今年 25 了
總結
- 要改變內容必須使用指標接收者
- 結構過大也考慮使用指標接收者