Go 结构体方法指针和值的区别

本文探讨了Go语言中结构体方法使用指针和值定义的区别,特别是在方法套娃情况下对属性修改的影响。实验结果显示,只有当调用链路全程使用指针方法时,属性修改才会保留。此外,值方法在内部会开辟新的属性地址空间,而指针方法则继承调用方的属性地址。
摘要由CSDN通过智能技术生成

众所周知,Go struct 定义方法时使用指针还是值的区别就是在方法内修改属性值时,用值定义的方法所做的修改只限于方法内,而指针则没有这个局限。

文章如果到这里就结束了,那么就很平平无奇了,于是我打算带大家去做个无聊但是值得思考的实验。

在开始之前,先写段简单的代码跑一下前面说到的东西,顺便让大家熟悉一下接下来实验代码的一些编码规则,哦对了,以下代码写于 2021.08,Go 版本是 1.16.5,如果你看到这篇文章的时候 Go 已经更新了很多个版本了,可能就不适用了。废话不多说,上代码:

package main

import "fmt"

type Foo struct {
    val int
}

/**
 *  在这里,我定义了两个 Set 方法,一个 P 结尾,一个 V 结尾,聪明的你肯定很快就反应过来了:
 *  P 即 Pointer,V 即 Value
 *
 * 另外我在这里加了个 callBy,方便追踪调用链
 */
func (f *Foo) SetP(v int, callBy string) {
    f.val = v
    fmt.Printf("In SetP():  call by:%s\tval:%d\n", callBy, f.val)
}

func (f Foo) SetV(v int, callBy string) {
    f.val = v
    fmt.Printf("In SetV():  call by:%s\tval:%d\n", callBy, f.val)
}


func main() {
    f := Foo{0}
    fmt.Printf("In main():                      val:%d\n", f.val)
    fmt.Println("=====================================")

    f.SetP(1, "main")
    fmt.Printf("In main(): after f.SetP(1):     val:%d\n", f.val)
    fmt.Println("=====================================")

    f.SetV(2, "main")
    fmt.Printf("In main(): after f.SetV(2):     val:%d\n", f.val)
    fmt.Println("=====================================")
}

运行结果:

In main():                      val:0
=====================================
In SetP():  call by:main        val:1
In main(): after f.SetP(1):     val:1
=====================================
In SetV():  call by:main        val:2
In main(): after f.SetV(2):     val:1

如我们预期,通过值定义的方法内对属性的修改并不会把影响带到外部。

接下来,开始我们的实验

假如方法套娃,会发生什么?
在我们日常开发时

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值