Go语言 '*'和'&'是什么意思?

kmb7vmvb  于 2023-08-01  发布在  Go
关注(0)|答案(6)|浏览(196)

我在做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: }

字符串
它们看起来像是C++中的指针。但我无法将这些概念与我们在这里所拥有的联系起来。换句话说,当我在Go的函数声明中使用'*'和'&'时,它们会做什么。
我知道引用和解引用是什么意思。我不明白我们如何在Go中使用指向函数的指针?例如第1行和第7行,这两行是做什么的?声明名为intial 1的函数返回指针?在第7行,我们使用return函数调用它。

nhaq1z21

nhaq1z211#

这可能是Go中最令人困惑的事情之一。基本上有三种情况你需要了解:

&运算符

&在你想要得到一个变量的 * 内存地址 * 的时候会出现在这个变量的前面。

*运算符

*位于保存内存地址的变量前面并解析它(因此它是&运算符的对应物)。它会得到指针所指向的东西,例如。*myString的值。

myString := "Hi"
fmt.Println(*&myString)  // prints "Hi"

字符串
或者更有用的是

myStructPointer = &myStruct
// ...
(*myStructPointer).someAttribute = "New Value"

*在Type前面

*放在 type 前面时,例如*string,它成为类型声明的一部分,所以你可以说“这个变量持有一个指向字符串的指针”。举例来说:

var str_pointer *string


因此,令人困惑的是,*实际上用于两个独立的(尽管相关的)东西。星星可以是运算符 * 或类型的 * 部分。

ggazkfy8

ggazkfy82#

你的问题与所举的例子不太相符,但我会尽量直截了当。
假设我们有一个名为a的变量,它保存整数5,另一个名为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)

字符串
总而言之,当使用 * 和&时,请记住 * 是用于设置您所指向的变量的值,而&是您所指向/想要指向的变量的地址。
希望这个答案能有所帮助。

jrcvhitl

jrcvhitl3#

这些 * 是 * 指针,就像我们在C++中使用的一样。
不同之处在于:

  • 在指针上调用一个方法时,* 总是 * 使用.,即pointer.method()的值。
  • 没有悬挂指针。返回一个指向局部变量的指针是完全有效的。Golang将确保对象的生存期,并在不再需要时对其进行垃圾收集。
  • 指针可以用new()创建,也可以通过创建一个对象object{}并用&获取其地址来创建。
  • Golang不允许指针算术(数组不会衰减为指针)和不安全的强制转换。所有向下转换都将使用变量的运行时类型进行检查,并且当示例的类型错误时,将panic或false作为第二个返回值返回,具体取决于您是否实际采用了第二个返回类型。
pengsaosao

pengsaosao4#

这是迄今为止理解@埃弗雷特答案中解释的所有三种情况的最简单方法

func zero(x int) {
  x = 0
}
func main() {
  x := 5
  zero(x)
  fmt.Println(x) // x is still 5
}

字符串
如果你需要一个变量在一个函数中被改变,那么把内存地址作为参数传递,并使用这个内存地址的指针来永久地改变这个变量。
注意在例子中int前面使用 *。这里它只是表示作为参数传递的变量是int类型的地址。

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

gj3fmq9x

gj3fmq9x5#

简单的解释。就像你想改变原始值一样

func zero(num *int){  // add * to datatype
  *num = 0 // can mutate the original number
}

i := 5
zero(&i) // passing variable with & will allows other function to mutate the current value of variable```

字符串

k97glaaz

k97glaaz6#

& Operator获取内存地址,而 * Operator**保存特定变量的内存地址。

相关问题