英文:
Weird behavior of big.NewInt anonymous variable
问题
在下面的代码片段中,我想进行一个非常简单的计算 d = a + b + c; a, b, c = b, c, d。它会迭代多次。
在第一次尝试中,我使用了一个匿名变量 big.NewInt(0).Add(a, b) 来获取 a + b 的结果,然后将其与 c 相加得到最终结果 a + b + c。但是从第二次迭代开始,d.Add(big.NewInt(0).Add(a, b), c) 改变了 c 的值,然后是 b,然后是 a,当然,最终的结果是错误的。
然而,第二次尝试的方法给了我正确的答案。有人可以告诉我为什么吗?
package main
import (
"fmt"
"math/big"
)
func main() {
// 第一次尝试
a := big.NewInt(1)
b := big.NewInt(2)
c := big.NewInt(3)
d := big.NewInt(0)
for i := 0; i < 5; i++ {
// d = a + b + c
d.Add(big.NewInt(0).Add(a, b), c)
fmt.Println(a, b, c, d)
// a <- b, b <- c, c <- d
a, b, c = b, c, d
fmt.Println(a, b, c, d)
}
fmt.Println(d)
// 第二次尝试
a = big.NewInt(1)
b = big.NewInt(2)
c = big.NewInt(3)
d = big.NewInt(0)
for i := 0; i < 5; i++ {
// d = a + b + c
d = big.NewInt(0).Add(big.NewInt(0).Add(a, b), c)
fmt.Println(a, b, c, d)
// a <- b, b <- c, c <- d
a, b, c = b, c, d
fmt.Println(a, b, c, d)
}
fmt.Println(d)
}
英文:
In the code snippet below, I want to make a very simple calculation d = a + b + c; a, b, c = b, c, d. It iterates several times.
In the first try, I make an anonymous variable big.NewInt(0).Add(a, b) to get the result of a + b, then add it and c to get the final result of a + b + c. But from the second iteration, d.Add(big.NewInt(0).Add(a, b), c) changed the value of c, then b, then a, and of course, the final result is wrong.
However, the second try's method gave me the right answer. Can anyone tell me why, please?
package main
import (
"fmt"
"math/big"
)
func main() {
// first try
a := big.NewInt(1)
b := big.NewInt(2)
c := big.NewInt(3)
d := big.NewInt(0)
for i := 0; i < 5; i++ {
// d = a + b + c
d.Add(big.NewInt(0).Add(a, b), c)
fmt.Println(a, b, c, d)
// a <- b, b <- c, c <- d
a, b, c = b, c, d
fmt.Println(a, b, c, d)
}
fmt.Println(d)
// second try
a = big.NewInt(1)
b = big.NewInt(2)
c = big.NewInt(3)
d = big.NewInt(0)
for i := 0; i < 5; i++ {
// d = a + b + c
d = big.NewInt(0).Add(big.NewInt(0).Add(a, b), c)
fmt.Println(a, b, c, d)
// a <- b, b <- c, c <- d
a, b, c = b, c, d
fmt.Println(a, b, c, d)
}
fmt.Println(d)
}
答案1
得分: 0
math/big.NewInt 返回一个指向 Int 的指针,所以在第一次迭代之后,c 和 d 都指向同一个对象。这意味着,在第二次迭代中,当你向 d 添加一些内容时,同样的变化也会反映在 c 中。然后你将 c 复制到 b,所以 b 也会指向同一个对象,在下一次迭代中,b 指向 a,所以在第三次迭代之后,所有 4 个变量都指向同一个 Int。
你的第二个循环可以工作是因为你每次都为 d 创建一个新的 Int,所以每次移动指针时,一个新的 Int(为 d 创建的那个)会被移动到 c,然后到 b,然后到 a。
英文:
math/big.NewInt returns a pointer to an Int, so after your first iteration, both c and d point to the same object. This means, in your second iteration, when you add something to d, the same change will be reflected in c. Then you copy c to b so b will also point to the same object, and on the next iteration b to a, so after your third iteration, all 4 variables point to the same Int.
Your second loop works because you create a new Int for d each time, so every time you shift the pointers, a new Int (the one which was created for d) gets moved to c, then to b, then to a.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论