将指针或副本的参数传递给函数

时间:2015-06-02 08:08:49

标签: go

我正在考虑Go指针,通过值或引用将变量作为参数传递给函数。在一本书中,我遇到了一个很好的例子,这是下面第一个传递指针的代码片段。

第一个版本按预期工作,在函数中,获取指针的参数会对变量本身进行更改,而不是对其副本进行更改。但是下面的第二个例子我正在修补它的副本上的作品。我认为它们应该等效,第二个用于处理作为参数传递的变量,而不是复制它。

基本上,这两个版本的函数表现不同?

version in the book,通过引用传递参数:

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,传递指针参数:

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"   
}

2 个答案:

答案 0 :(得分:4)

他们为什么要表现得相同?在第一个示例中,您传递指针(到int),在第二个示例中,您传递int值。

第二个示例中发生的是您传递int值。函数中的参数像局部变量一样工作。将创建一个名为a的{​​{1}}类型的局部变量,并使用您传递的值(int,即3的值)进行初始化。这个局部变量可以像任何其他变量一样进行寻址。

您获取其地址(x)并递增此指针指向的值(变量p := &a本身)。然后返回它指向的值,即a的递增值。

在您调用此a函数的位置之外,未修改add1()的值,因为仅修改了本地副本x

答案 1 :(得分:2)

golang中的所有内容都是pass by value,这意味着该函数始终会获取正在传递的内容的副本。 在第二个示例中,x的值实际上已发送到函数add,因此您对该副本所做的任何修改都不会影响原始x

请参阅pass by value