big.NewInt匿名变量的奇怪行为

huangapple go评论68阅读模式
英文:

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 (
	&quot;fmt&quot;
	&quot;math/big&quot;
)

func main() {
	// first try
	a := big.NewInt(1)
	b := big.NewInt(2)
	c := big.NewInt(3)
	d := big.NewInt(0)
	for i := 0; i &lt; 5; i++ {
		// d = a + b + c
		d.Add(big.NewInt(0).Add(a, b), c)
		fmt.Println(a, b, c, d)
		// a &lt;- b, b &lt;- c, c &lt;- 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 &lt; 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 &lt;- b, b &lt;- c, c &lt;- d
		a, b, c = b, c, d
		fmt.Println(a, b, c, d)
	}

	fmt.Println(d)
}

答案1

得分: 0

math/big.NewInt 返回一个指向 Int 的指针,所以在第一次迭代之后,cd 都指向同一个对象。这意味着,在第二次迭代中,当你向 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.

huangapple
  • 本文由 发表于 2017年2月25日 13:57:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/42452520.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定