值传递和引用类型传递

在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, 我今年 22 了

我们改的仅仅是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, 我今年 22 了

总结

  • 要改变内容必须使用指针接收者
  • 结构过大也考虑使用指针接收者
本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 2

@motecshine 嗯嗯,是的,应该是引用类型

4年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!