[英]GoLang pointers are behaving wierd
為什么更改 node2.Next 會影響下面代碼中的 node2?
import "fmt"
type ListNode struct {
Val int
Next *ListNode
}
func main() {
node1 := ListNode{Val:10 , Next:nil}
node2 := ListNode{Val:100 , Next:&node1}
temp := node2
if(temp == node2){
fmt.Println("Equalssss1")
}
node2.Next = &(ListNode{1 , nil})
if(temp == node2){
fmt.Println("Equalssss2")
}
}
基本上為什么不打印“Equalsss2”? 我感覺既然改了node2.Next但沒改node2,node2應該等於temp 為什么不是呢?
您的代碼中沒有行為不當的指針。 我懷疑你認為的指針實際上並不是指針,因此你很困惑。
在您的代碼中, node1
和node2
是ListNode
結構,即 _ value types 。 當您將node2
分配給temp
時, temp
會保存node2
的副本,而不是指向它的指針或引用。
在 Go 中,(簡單來說)如果兩個結構值具有相同的類型並且由可比較的字段組成且都被評估為相等,則它們是相等的。
當您最初比較node2
和temp
時,這兩個值中每個值的所有字段的值都相同,因此temp == node2
的計算結果為真。
然后更改node2
的Next
字段,因此當您再次比較temp == node2
時,它們不再相等,因為它們在該字段的值上不同。
要獲得您期望的行為, node1
和node2
需要是指向ListNode
的指針:
type ListNode struct {
Val int
Next *ListNode
}
func main() {
node1 := &ListNode{Val: 10, Next: nil}
node2 := &ListNode{Val: 100, Next: node1}
temp := node2
if temp == node2 {
fmt.Println("Equalssss1")
}
node2.Next = &(ListNode{1, nil})
if temp == node2 {
fmt.Println("Equalssss2")
}
}
temp
現在也是指向ListNode
的指針,而不是ListNode
值的副本; temp
被初始化為引用node2
引用的同一個ListNode
。 即指針temp
和node2
相等; 他們都指向同一個ListNode
。
現在,當您更改node2.Next
時,這不會影響temp
仍然只是node2
指針的副本這一事實,並且由於node2
本身(指針)和temp
的值都沒有改變,它們仍然相等。
即,如果您使用指針,您的代碼將按預期運行。 如果您認為指針表現得“怪異”,那是因為在這種情況下,您實際上並沒有使用指針。 :)
正如您問題的評論者試圖指出的那樣,這里沒有發生任何奇怪的事情。 在您的第一個條件之后添加:
fmt.Printf("temp is at %p and temp.Next is at %p\nnode2 is at %p and node2.Next is at %p\n", &temp, temp.Next, &node2, node2.Next)
這將是 output:
temp is at 0xc00009e240 and temp.Next is at 0xc00009e220
node2 is at 0xc00009e230 and node2.Next is at 0xc00009e220
並嘗試在第二個條件之后添加此行:
fmt.Printf("temp.Next has Val: %d\nnode2.Next has Val: %d\n", temp.Next.Val, node2.Next.Val)
這將是 output:
temp.Next has Val: 10
node2.Next has Val: 1
你可以在這里看到結果。
node2
和temp
指向不同的對象,在您修改node.Next
之前,這兩個對象具有相同的字段值。 您的分配temp:= node2
make 創建了結構類型的新實例,並復制了源 object 中的值。它不會創建指向node
object 的指針 - 如果有,則更改node2.<field>
也會更改temp.<field>
。 這有點令人困惑,因為在 go 中(與 C 不同)您不需要取消引用指針/使用不同的訪問器語法來訪問結構字段,因此以下內容完全沒問題:
temp := &node2
node2.Val = 500
fmt.Printf("%d == %d\n, temp.Val, node2.Val)
最終,這里的一切都如人們所想的那樣發生着。 換句話說,您的第一個條件是檢查相等性而不是身份。 具有相同值(平等)的不同對象(身份)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.