在Go函数中通过引用和值传递 [英] Passing by reference and value in Go to functions

查看:68
本文介绍了在Go函数中通过引用和值传递的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对在Go中传递引用和值感到困惑.

I am a bit confused about passing by reference and value in Go.

我已经看到了在类型前面*的解释.

I've seen this explained of the * in front of a type.

    在类型名称前面的
  • 表示已声明的变量将存储该类型的另一个变量的地址(而不是该变量的值) 类型).
  • in front of a type name, means that the declared variable will store an address of another variable of that type (not a value of that type).

这对我来说毫无意义.

在Java中,如果我要将数据库实例传递给函数,我会这样做

In Java if I was passing a Database instance into a function I would do

 databaseFunction(DatabaseType db) {
      // do something
}

但是在go示例中,它是这样传递的.

However in the go example I have it's passed like so.

func PutTasks(db *sql.DB) echo.HandlerFunc {

}

为什么我们需要在类型前面加上星号?

Why do we need to have the asterisk in front of the type?

根据这份备忘单,我发现了.

According to this cheat sheet, I found.

func PrintPerson(p * Person)仅接收指针地址 (参考)

func PrintPerson(p *Person) ONLY receives the pointer address (reference)

我不明白为什么我只想发送一个指针地址作为参数.

I don't understand why I would only want to send a pointer address as a parameter.

推荐答案

首先,从技术上讲,Go仅具有按值传递.将指针传递给对象时,是按值传递指针,而不是按引用传递对象.差异是细微的,但有时是相关的.例如,您可以覆盖对调用者没有影响的指针值,而不是取消引用并覆盖它指向的内存.

First, Go technically has only pass-by-value. When passing a pointer to an object, you're passing a pointer by value, not passing an object by reference. The difference is subtle but occasionally relevant. For example, you can overwrite the pointer value which has no impact on the caller, as opposed to dereferencing it and overwriting the memory it points to.

// *int means you *must* pass a *int (pointer to int), NOT just an int!
func someFunc(x *int) {
    *x = 2 // Whatever variable caller passed in will now be 2
    y := 7
    x = &y // has no impact on the caller because we overwrote the pointer value!
}

关于您的问题为什么我们需要在类型前面加星号?":星号表示该值的类型为指向sql.DB的指针,而不是类型为sql.DB的值.这些是不可互换的!

As to your question "Why do we need to have the asterisk in front of the type?": The asterisk indicates that the value is of type pointer to sql.DB, rather than a value of type sql.DB. These are not interchangeable!

为什么要发送指针地址?这样,您就可以在函数的调用者和函数主体之间共享值,并且在函数内部进行的更改会反映在调用者中(例如,指针是设置者"的唯一方式方法可以对一个对象起作用). Java始终通过引用传递对象,而Go始终通过值传递(即,它在函数中创建值的副本);如果您将某些内容传递给函数,并且该函数修改了该值,则调用者将看不到这些更改.如果要更改以在函数外部传播,则必须传递一个指针.

Why would you want to send a pointer address? So that you can share the value between the caller of a function and the function body, with changes made inside the function reflected in the caller (for example, a pointer is the only way that a "setter" method can work on an object). While Java passes objects by reference always, Go passes by value always (i.e. it creates a copy of the value in the function); if you pass something to a function, and that function modifies that value, the caller won't see those changes. If you want changes to propogate outside the function, you must pass a pointer.

另请参见:关于指针的游览"部分有关地址运算符的转到规范"部分

这篇关于在Go函数中通过引用和值传递的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆