亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Go中指針的常見錯誤

Go中指針的常見錯誤

Go
MMTTMM 2022-01-04 14:05:06
我已經很長時間沒有使用指針了,當我使用指針時,它只是在學術環境中使用,多虧了 C#/Java/scala,我現在有點生疏了。人們在 Golang 中使用指針會犯哪些常見錯誤?有沒有測試你是否正確使用它們的方法?我想在出現問題之前總是很難檢測到內存泄漏。
查看完整描述

2 回答

?
蠱毒傳說

TA貢獻1895條經驗 獲得超3個贊

鑒于 Go 是垃圾收集的并且不允許指針算術,因此您可以做錯的事情并不多。您可以unsafe為此使用包,但它的名稱不言而喻 - 它是不安全的。

nil指針還在。取消引用它們會導致恐慌,這有點像 C#/Java 中的異?!銜玫揭粋€清晰的錯誤描述和它發生的堆棧跟蹤。

內存泄漏 - GC 幾乎可以為您做所有事情,就像在 C#/Java 中一樣。但是我知道有一個特殊情況 - 切片。刪除一個元素通常是通過像這樣創建另一個切片來完成的:

a = append(a[:i], a[i+1:]...)

此代碼可能會泄漏您刪除的元素。那是因為在內部 slice 是一個包含數組(只是一個指針)、長度和容量的結構體。當您刪除一個元素時,新切片可能包含相同的數組,它仍然會引用您刪除的元素。GC 不會釋放它。要解決這個問題,您需要在刪除元素之前將其歸零。

并且還有指針與值方法接收器的混淆。這不是錯誤,更像是您必須做出和理解的設計決策。帶有值接收器的方法將獲得接收器的副本,它不能修改狀態。所以如果你想修改狀態,那么你需要指針接收器。此外,如果您的結構很大并且您不希望每次調用方法時都復制它們,您可能還想使用指針接收器。


查看完整回答
反對 回復 2022-01-04
?
米琪卡哇伊

TA貢獻1998條經驗 獲得超6個贊

我發現的常見錯誤是人們忘記了復雜結構中的指針。


每個 slice、map、interface 都是一個指針。當您有一個包含另一個包含指針的結構的結構時,您可能會看到S1{s2: S2},并且您認為這樣復制結構很好:a=b當實際上它不好時,如在 s2 內部,一個指針變量,比方說p,會有他們的地址被復制,而不是它指向的值。當 yoy 修改在 *a.s2.p 處找到的值時,*b.s2.p 將返回相同的值。


package main


import (

    "fmt"

)


type S1 struct {

    v int

    s2 S2

}


type S2 struct {

    p *int

}


func main() {

    x := 1

    b := S1{v: 10, s2: S2{p: &x}}

    a := b

    fmt.Printf("a = %+v\nb = %+v\n*a.s2.p = %d\n*b.s2.p = %d\na.s2.p = %p\nb.s2.p = %p\n", a, b, *a.s2.p, *b.s2.p, a.s2.p, b.s2.p)

    *a.s2.p = 5

    fmt.Printf("*a.s2.p = %d\n*b.s2.p = %d\na.s2.p = %p\nb.s2.p = %p\n", *a.s2.p, *b.s2.p, a.s2.p, b.s2.p)

}

http://play.golang.org/p/KQ99KICgbu


這是一個非常簡單的示例,看起來很明顯存在問題,但在更大的應用程序中,這可能不那么明顯。


頻道也會出現此問題。如果您發送一個指針,您將在另一端獲得相同的指針(指針值的副本,這是一個地址)。在這種情況下,與第一種情況一樣,安全的解決方案是使用 Clone 函數來創建克隆對象。您通過您的頻道發送克隆,并且不再在發送方使用它。


查看完整回答
反對 回復 2022-01-04
  • 2 回答
  • 0 關注
  • 216 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號