值傳遞和引用傳遞

哒喇發表於2024-08-02

在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 了

總結

  • 要改變內容必須使用指標接收者
  • 結構過大也考慮使用指標接收者

相關文章