Golang中'*'和'&'的含义是什么?

Dav*_*vid 11 go

我是Golang的新手,我正在做http://tour.golang.org/.任何人都可以解释我的第1,3,5和7行这个功能特别是'*'和'&'做什么?我的意思是在函数声明中提到它们,它们应该/预期会做什么?玩具示例:

1: func intial1(var1 int, var2 int, func1.newfunc[]) *callproperfunction {
2:
3: addition:= make ([] add1, var1)
4: for i:=1;i<var2;i++ {
5:   var2 [i] = *addtother (randomstring(lengthofcurrent))
6:   }
7: return &callproperfunction {var1 int, var2 int, func1.newfunc[], jackpot}
8: }
Run Code Online (Sandbox Code Playgroud)

它们似乎是我们在C++中的指针.但是我无法将这些概念与我们在这里的内容联系起来.换句话说,当我在Go中的函数声明中使用'和'时,'&'做什么.

编辑:我知道什么参考和解引用意味着什么.我无法理解的是:我们如何使用指向函数的指针是Golang.例如第1行和第7行,这两行做什么?我们声明了一个名为intial1的函数,它返回一个指针?在第7行中,我们使用return函数调用它.

小智 24

你的问题与给出的例子不太匹配,但我会尽量直截了当.

假设我们有一个名为变量a5的变量和另一个名为的变量p,它将成为一个指针.这就是*&进入游戏.

使用它们打印变量可以生成不同的输出,因此一切都取决于具体情况和使用情况.使用*&可以保存你的代码行(这在小项目中并不重要)并使你的代码更美观/可读.

&返回以下变量的内存地址.

*返回以下变量的(应该保存变量的内存地址,除非你想获得奇怪的输出并且可能因为你访问计算机的RAM而出现问题)

var a = 5
var p = &a // p holds variable a's memory address
fmt.Printf("Address of var a: %p\n", p)
fmt.Printf("Value of var a: %v\n", *p)

// Let's change a value (using the initial variable or the pointer)
*p = 3 // using pointer
a = 3 // using initial var

fmt.Printf("Address of var a: %p\n", p)
fmt.Printf("Value of var a: %v\n", *p)
Run Code Online (Sandbox Code Playgroud)

总而言之,当使用*和&时,记住*用于设置您指向的变量的值,而&是您指向/想要指向的变量的地址.

希望这个答案有所帮助


Eve*_*ett 24

这可能是Go中最令人困惑的事情之一.基本上你需要了解3个案例:

&运营商

&当你想获得变量的内存地址时,它会转到变量前面.

*运营商

*进入一个包含内存地址并解析它的变量前面(因此它与&运算符相对应).它会指向指针指向的东西,例如*myString.

myString := "Hi"
fmt.Println(*&myString)  // prints "Hi"
Run Code Online (Sandbox Code Playgroud)

或更有用的,像

myStructPointer = &myStruct
// ...
(*myStructPointer).someAttribute = "New Value"
Run Code Online (Sandbox Code Playgroud)

* 在一个类型前面

*放在类型前面时,例如*string,它成为类型声明的一部分,因此您可以说"此变量包含指向字符串的指针".

所以令人困惑的是,*真正被用于2个独立的(尽管是相关的)事物.星可以是操作员类型的一部分.

  • 这是 IMO 的最佳解释,应该是选定的答案 (9认同)
  • 我认为 fmt.Println(*&amp;String) 应该是 fmt.Println(*&amp;myString) 。除此之外:很好的解释。 (2认同)

tka*_*usl 11

这些我们在C++ 中的指针.

不同之处是:

  • ->总是 使用.,而不是在指针上调用方法pointer.method().

  • 没有悬空指针.返回指向局部变量的指针是完全有效的.Golang将确保对象的生命周期,并在不再需要时对其进行垃圾收集.

  • 可以使用new()或通过创建对象object{}并使用其地址来创建指针&.

  • Golang不允许指针算术(数组不会衰减到指针)和不安全的转换.将使用变量的运行时类型检查所有向下转换,或者panic当实例的类型错误时返回false作为第二个返回值,具体取决于您是否实际采用第二个返回类型.


小智 9

这是迄今为止理解@Everett 回答中解释的所有三种情况的最简单方法

func zero(x int) {
  x = 0
}
func main() {
  x := 5
  zero(x)
  fmt.Println(x) // x is still 5
}
Run Code Online (Sandbox Code Playgroud)

如果您需要在函数内部更改变量,则将内存地址作为参数传递,并使用此内存地址的指针永久更改变量。

注意示例中 int 前面 * 的使用。这里它只代表作为参数传递的变量是int类型的地址。

func zero(xPtr *int) {
  *xPtr = 0
}
func main() {
  x := 5
  zero(&x)
  fmt.Println(x) // x is 0
}
Run Code Online (Sandbox Code Playgroud)

  • 至少要从您复制此内容的地方给予应有的认可。[golang-book.com/books/intro/8](https://www.golang-book.com/books/intro/8) (6认同)