V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
chinafengzhao
V2EX  ›  Google

golang 中的值传递和指针传递的理解?

  •  
  •   chinafengzhao · 2020-11-20 12:10:13 +08:00 · 2899 次点击
    这是一个创建于 1456 天前的主题,其中的信息可能已经有所发展或是发生改变。

    上代码

    
    package main 
    
    import(
        "fmt"
    )
    
    // 声明一个基于 int 的类型 Integer
    type Integer int
    
    
    // 基于指针的传递( Integer 类型的指针变量 a )
    func (a* Integer) Add_pointer (b Integer) {
        *a += b
    }
    
    // 基于值的传递,按理,经过这次调用,也是对 a 进行重新赋值,为什么调用之后,再去打印,还是以前的值?
    func (a Integer) Add_value (b Integer) {
        a += b
    }
    
    
    func main() {
        var a Integer = 1
        var b Integer = 1
        a.Add_pointer(2)
        b.Add_value(2)
        fmt.Println("a =", a)
        fmt.Println("b =", b)
    }
    
    // a=3
    // b=1
    
    
    

    为什么会有这个输出?

    14 条回复    2020-11-20 19:14:27 +08:00
    yatsun
        1
    yatsun  
       2020-11-20 12:15:26 +08:00
    学过 c 吗,子函数里的是形参,是额外开辟的空间,不会改变原本的值
    BoarBoar
        2
    BoarBoar  
       2020-11-20 12:16:46 +08:00
    C 语言学过吧?一样的
    指针就是变量 a 的内存地址,在原变量上+2
    对于 b 实际上是新创建了一个变量,暂且叫做 b(1)吧,b(1)实际上是新的一块内存,+2 后对原变量没影响
    raaaaaar
        3
    raaaaaar  
       2020-11-20 12:17:12 +08:00 via Android   ❤️ 6
    忘记指针,忘记值传递,忘记传值这些概念。
    记住:一个是操作一块内存,一个是操作两块内存。
    shangyes
        4
    shangyes  
       2020-11-20 12:29:15 +08:00
    方法是函数
    ```golang
    func Add_pointer(a* Integer, b Integer) {
    *a += b
    }

    func Add_value(a, b Integer) {
    a += b
    }
    ```
    yrj
        5
    yrj  
       2020-11-20 12:30:53 +08:00 via iPad
    @raaaaaar 哈哈,这么理解挺好
    cholerae
        6
    cholerae  
       2020-11-20 14:41:30 +08:00   ❤️ 1
    go 里面只有值传递,记着这一点就行了。只不过有时候这个值是一个指针。
    cco
        7
    cco  
       2020-11-20 14:46:20 +08:00
    值传递!没有别的。
    xkeyideal
        8
    xkeyideal  
       2020-11-20 14:52:08 +08:00
    从 C 语言的角度来说,a.Add_pointer(2) 这一行代码都不会编译通过的,另外呢,无脑指针会比较方便,但指针并非都是最优解
    lance6716
        10
    lance6716  
       2020-11-20 15:05:25 +08:00 via Android
    其实一直对这个很迷惑,尤其是到了含有指针的结构体时:传指针的地址就不叫传值了吗
    joesonw
        11
    joesonw  
       2020-11-20 15:07:00 +08:00
    4 楼是正解. go 不是 OOP, 没有 class, 都只是方法而已.
    例如

    type S struct {}

    func (s *S) Say() {
    println("hello world")
    }

    func main() {
    var s *S
    s.Say()
    }

    是正常运行的
    https://play.golang.org/p/7pQ51IZ-4rB
    chor02
        12
    chor02  
       2020-11-20 18:32:19 +08:00 via iPhone
    可以理解為 func (a* Integer)和 func (a Integer)中的 a*和 a 也是一個參數
    ghjacky
        13
    ghjacky  
       2020-11-20 19:11:30 +08:00
    这个是 go 里边的 receiver,不过类似于参数传递,都是值传递(拷贝了一份数据),指针传递也是值传递,只不过指针类型的数据本身就是一内存地址,所以,更改指针指向内存空间的值,原始值也会改变啊。
    ScepterZ
        14
    ScepterZ  
       2020-11-20 19:14:27 +08:00
    你这句话属于瞎说……这个 a 是复制来的,不是原来那个
    基于值的传递,按理,经过这次调用,也是对 a 进行重新赋值
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   4116 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 10:14 · PVG 18:14 · LAX 02:14 · JFK 05:14
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.