在下面,a
發生了意外的變化。 d
使用 a
(*a
) 的值構造,然後 d.c
被正確更改。但是為什麼 a
更改為 Exp
的第一個參數?
type Decimal struct { c big.Int // coefficient q big.Int // exponent } a := big.NewInt(1) b := big.NewInt(2) d := Decimal{*a, *b} d.c.Exp(big.NewInt(11), big.NewInt(2), big.NewInt(0)) fmt.Println(a, b, d) // 11 2 {{false [121]} {false [2]}}
我希望 a
保持不變。
編輯:要新增的是,我還列印了a
、b
、d.c
、d.q
的指標位址,並且在Exp
之前和之後都不同: fmt.Printf("%p %p %p %p \n", &a, &b, &d.c, &d.q)
這是一個更簡單的範例,顯示了相同的內容:
x := big.NewInt(1) y := *x y.Exp(big.NewInt(11), big.NewInt(2), big.NewInt(0)) fmt.Println(x) // 11 fmt.Println(&y) // 121
首先要考慮的是y.Exp
「設定z = x**y mod |m|
(即m
的符號被忽略),並傳回z。";因此y
的值發生變化(如上所示)。
要了解為什麼會改變 x
的值,可以從文件開始:
「淺複製」正是上面的 y := *x
(或程式碼中的 d := Decimal{*a, *b}
)所做的。所以解決方案是遵循上面的建議:
x := big.NewInt(1) y := new(big.Int).Set(x) // Avoid shallow copy y.Exp(big.NewInt(11), big.NewInt(2), big.NewInt(0)) fmt.Println(x) // 1 fmt.Println(y) // 121
(您可以在範例中執行類似的操作)。
要解釋為什麼會發生這種情況,您需要查看big.Int
已定義。這需要檢查一些文件,但歸結為(簡化!):
type Int struct { neg bool // sign abs []uint // absolute value of the integer }
因此,對其進行淺複製將導致兩個實例的切片共享相同的後備數組 (當切片中的元素發生更改時,這可能會導致不可預測的結果)。
在您的範例中,當 set
已執行。展示這一點的更簡單方法是:
x := big.NewInt(1) y := *x y.Set(big.NewInt(11)) fmt.Println(x) // 11 fmt.Println(&y) // 11
以上是Golang 在結構體中使用 Exp for big.Int 奇怪地改變了值的詳細內容。更多資訊請關注PHP中文網其他相關文章!