Go passing parameters of pointers or copies to functions

huangapple go评论84阅读模式
英文:

Go passing parameters of pointers or copies to functions

问题

我正在思考Go语言中的指针问题,通过值或引用将变量作为参数传递给函数。在一本书中,我遇到了一个很好的例子,即下面的第一个代码片段,它演示了如何传递指针。

第一个版本按预期工作,在接受指针参数的函数中对变量本身进行更改,而不是对其副本进行更改。但是,我正在尝试的第二个示例在副本上进行操作。我原以为它们应该表现相同,并且第二个示例应该在传递的变量上进行操作,而不是在副本上进行操作。

基本上,这两个版本的函数有何不同之处?

书中的版本,通过引用传递参数:

package main

import (
	"fmt"
)

// 简单的函数,将1加到a上
func add1(a *int) int {
    *a = *a+1 // 改变了a的值
    return *a // 返回a的新值
}

func main() {
    x := 3

    fmt.Println("x =", x)  // 应该打印"x = 3"

    x1 := add1(&x)  // 调用add1(&x),传递x的内存地址

    fmt.Println("x+1 =", x1) // 应该打印"x+1 = 4"
    fmt.Println("x =", x)    // 应该打印"x = 4"
}

我尝试的替代版本,通过指针参数传递:

package main

import (
	"fmt"
)

// 简单的函数,将1加到a上
func add1(a int) int {
    p := &a
    *p = *p+1 // 改变了a的值
    return *p // 返回a的新值
}

func main(){
    fmt.Println("this is my go playground.")

    x := 3

    fmt.Println("x =", x)  // 应该打印"x = 3"

    x1 := add1(x)  // 调用add1(x)

    fmt.Println("x+1 =", x1) // 应该打印"x+1 = 4"
    fmt.Println("x =", x)    // 应该打印"x = 4"
}
英文:

I am contemplating on the Go pointers, passing variables as parameters to functions by value or by reference. In a book I have encountered a good example, which is the first code snippet below, on passing a pointer.

The first version is working as expected, in function that takes parameter of a pointer makes changes to the variable itself, not on a copy of it. But the second example below I am tinkering with works on a copy of it. I have thought they should behave equivalently, and second one to work on the variable passed as parameter, not on copy of it.

Essentially, what these two versions of the function is behaving different?

version in the book, passing parameters by reference:

package main

import (
	"fmt"
)
// simple function to add 1 to a
func add1(a *int) int {
    *a = *a+1 // we changed value of a
    return *a // return new value of a
}

func main() {
    x := 3

    fmt.Println("x = ", x)  // should print "x = 3"

    x1 := add1(&x)  // call add1(&x) pass memory address of x

    fmt.Println("x+1 = ", x1) // should print "x+1 = 4"
    fmt.Println("x = ", x)    // should print "x = 4"
}

my alternative tinkering version, passing pointer parameter:

package main

import (
	"fmt"
)
// simple function to add 1 to a
func add1(a int) int {
	p := &a
    *p = *p+1 // we changed value of a
    return *p // return new value of a
}
func main(){
	fmt.Println("this is my go playground.")
	
	    x := 3

	    fmt.Println("x = ", x)  // should print "x = 3"

	    x1 := add1(x)  // call add1(&x) pass memory address of x

	    fmt.Println("x+1 = ", x1) // should print "x+1 = 4"
	    fmt.Println("x = ", x)    // should print "x = 4"	
}

答案1

得分: 4

为什么它们要表现得等价呢?在第一个例子中,你传递了一个指针(指向 int 类型),而在第二个例子中,你传递了一个 int 值。

在第二个例子中发生的是,你传递了一个 int 值。函数中的参数工作方式类似于局部变量。将创建一个名为 a 的局部变量,其类型为 int,并将其初始化为你传递的值(即 x 的值为 3)。这个局部变量可以像其他变量一样被寻址。

你获取它的地址(p := &a),并增加该指针指向的值(即变量 a 本身)。然后你返回该指针指向的值,即 a 的增加后的值。

在调用 add1() 函数的地方之外,x 的值不会被修改,因为只有局部副本 a 被修改了。

英文:

Why should they behave equivalently? In the first example you pass a pointer (to int), in the second example you pass an int value.

What happens in the 2nd example is that you pass an int value. Parameters in functions work like local variables. A local variable called a of type int will be created, and will be initialized with the value you passed (3 which is the value of x). This local variable is addressable like any other variables.

You take its address (p := &a) and you increment the value pointed by this pointer (which is variable a itself). And you return the value pointed by it which is the incremented value of a.

Outside from where you called this add1() function, the value of x is not modified because only the local copy a was modified.

答案2

得分: 2

golang中,一切都是按值传递的,这意味着函数总是得到传递的东西的副本。
在你的第二个例子中,x的值实际上被发送到函数add,所以对副本所做的任何修改都不会影响原始的x

参见按值传递

英文:

Everything in golang is pass by value, which means the function always gets a copy of the thing being passed.
In your second example, the value of x is actually sent to the function add, so any modification you made to the copy wont affect the original x.

See pass by value

huangapple
  • 本文由 发表于 2015年6月2日 16:08:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/30590689.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定