gpt4 book ai didi

pointers - 理解 Go 中的指针

转载 作者:IT王子 更新时间:2023-10-29 00:59:31 26 4
gpt4 key购买 nike

我想了解指针在 Go 中的工作原理。总的来说,我对指针没有什么经验,因为我主要使用 javascript。

我写了这个虚拟程序:

func swap(a, b *int) {
fmt.Println("3", &a, &b)
*a, *b = *b, *a

fmt.Println("4", a, b)
}
func main() {
x := 15
y := 2

fmt.Println("1", x, y)
fmt.Println("2", &x, &y)
swap(&x, &y)
fmt.Println("5", x, y)
}

打印以下结果:

$ go run test.go
1 15 2
2 0x208178170 0x208178178
3 0x2081ac020 0x2081ac028
4 0x208178178 0x208178170
5 2 15

我有几个问题:

  1. 据我了解,&x 给出了存储x 的地址。要获得 x 的实际值,我需要使用 *x。然后,我不明白为什么&x*int类型。由于 *x&x 都是 *int 类型,所以我根本不清楚它们的区别。

  2. 在我的交换函数中,使用 *a, *b = *b, *a 和使用 a, b = b, a 有什么区别>?两者都有效,但我无法解释为什么...

  3. 为什么第 2 步和第 3 步打印的地址不同?

  4. 为什么我不能直接修改地址,比如把&b赋值给&a

非常感谢您的帮助

最佳答案

1) 语言的混淆导致您认为 *x&x 是同一类型。正如 Not_a_Golfer 所指出的,* 在表达式和类型名称中的用法是不同的。 *x 在你的 main() 是无效的语法,因为 * 在表达式中试图获得指针指向的值,但是 x 不是一个指针(它是一个 int)。

我认为您在考虑以下事实:当您使用 &x 获取指向 x 的指针时,添加到类型名称的字符是 * 形成 *int。我可以看出 &var 让你得到 *typ 而不是 &typ 是多么令人困惑。另一方面,如果他们将 & 放在类型名称上,那在其他情况下会造成混淆。有些技巧是不可避免的,就像人类语言一样,通过使用比单独讨论更容易学习。

2) 再一次证明这个假设是不准确的:a, b = b, a 交换了 swap 函数查看的指针,但不交换main 视角的值和最后一行输出更改为 5 15 2:http://play.golang.org/p/rCXDgkZ9kG

3) swap 正在打印指针变量的地址,而不是底层整数的地址。您将打印 ab 以查看整数的地址。

4) 我假设,也许是错误的,您希望您可以使用 & 语法交换任意变量指向的位置,如 &x, &y = &y , &x, 而无需声明指针变量。有一些歧义,如果那不是你想要的,我不确定这部分答案是否对你有帮助。

对于许多“为什么我不能……”的问题,最简单的答案是“因为他们以这种方式定义了语言”。但是去为什么有点这样,我认为你需要在某个时候(或 another type implemented using pointers, like maps or slices )将变量声明为指针,因为指针带有陷阱:你可以做例如,一段代码中的某些东西以意想不到的方式改变了其他代码的局部变量。所以无论你看到 *int 出现在哪里,它都在告诉你你可能不得不担心(或者,你能够使用)诸如 nil 指针之类的事情,来自多段代码等

与其他语言相比,Go 在使指针罩显式化方面更加保守:例如,C++ 具有“引用参数”(int& i) 的概念,您可以在其中执行您的 swap(x,y) 没有 & 或指针出现在 main 中。换句话说,在具有引用参数的语言中,您可能必须查看函数的声明才能知道它是否会更改其参数。对于 Go 人员来说,这种行为有点太令人惊讶/隐含/太棘手了。


所有的引用和取消引用都需要一些思考,你可能只需要花一些时间来理解它;不过,希望所有这些都能有所帮助。

关于pointers - 理解 Go 中的指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27830605/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com