pointers - 在 Go 函数中通过引用和值传递

标签 pointers go

我对在 Go 中通过引用和值传递有点困惑。

我看过这个对类型前面的 * 的解释。

  • 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 中,如果我将一个数据库实例传递给一个函数,我会这样做

 databaseFunction(DatabaseType db) {
      // do something
}

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

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

}

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

根据这个备忘单,我找到了。

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

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

最佳答案

首先,Go 在技术上只有按值传递。传递指向对象的指针时,您是按值传递指针,而不是按引用传递对象。差异很微妙,但有时是相关的。例如,您可以覆盖对调用者没有影响的指针值,而不是取消引用它并覆盖它指向的内存。

// *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。它们不可互换!

为什么要发送指针地址?这样您就可以在函数的调用者和函数体之间共享值,函数内部所做的更改会反射(reflect)在调用者中(例如,指针是“setter”唯一的方式方法可以作用于一个对象)。 Java 总是通过引用传递对象,而 Go 总是通过值传递(即它在函数中创建值的副本);如果您将某些内容传递给函数,并且该函数修改了该值,则调用者将看不到这些更改。如果您希望更改传播到函数外部,则必须传递一个指针。

另请参阅:Go tour section on Pointers , Go spec section on pointers , Go spec section on the address operators

关于pointers - 在 Go 函数中通过引用和值传递,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47296325/

相关文章:

c++ - 如何制作指向另一个子 vector 中项目的指针 vector ?

c# - 为什么用方法返回指针会使测试在 Debug模式下失败?

go - 尝试使用追加删除字符串数组中的连续项目

apache - 具有 Apache 多个 VirtualHosts 的 Golang webapp

c - C中数组的问题

c - 'calloc' 不会自动消耗 RAM 中的内存

c# - GCHandle 获取 .net 对象的地址(指针)

mysql - 在 mysql 中使用 gorm 插入类型 []byte 引发 "Error 1241: Operand should contain 1 columns(s)"

heroku - 在 Heroku 上使用 Imagemagick 部署 Go 应用程序

http - 使用 http 劫持者有什么好处