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

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

我不明白什么時候在go上使用指針

我不明白什么時候在go上使用指針

Go
弒天下 2022-08-24 10:41:35
我正在做一個關于圍棋語言的游覽,我有一個關于指針的問題。示例代碼 (https://tour.golang.org/methods/19):package mainimport (    "fmt"    "time")type MyError struct {    When time.Time    What string}func (e *MyError) Error() string {    return fmt.Sprintf("at %v, %s",        e.When, e.What)}func run() error {    return &MyError{        time.Now(),        "it didn't work",    }}func main() {    if err := run(); err != nil {        fmt.Println(err)    }}在這種情況下,它使用*MyError和&MyError,但我試圖刪除*和&,它工作正常。為什么他們在此示例中使用指針?與正態變量有什么區別?何時應使用指針?
查看完整描述

2 回答

?
UYOU

TA貢獻1878條經驗 獲得超4個贊

“我什么時候應該使用指針?”是一個非常大的問題,沒有一個簡單的答案。指針是一種傳遞對值(而不是值本身)的引用的方法,允許您修改原始值或“查看”對該值的修改。它還可以防止復制,在非常有限的情況下,復制可能是性能改進(不要一直傳遞指針,因為它可能是性能改進)。最后,指針還允許您表示“虛無”,每個指針都可以是 。這既是祝福也是詛咒,因為您必須在訪問每個指針之前檢查它是否是。nilnil

在您的具體示例中,返回工作的原因是因為您的函數對值(指向 )而不是對自身的值進行操作。這意味著 實現接口,因此可以分配給類型,因此可以從任何期望將 a 作為返回值的函數返回。&MyErrorError()*MyErrorMyErrorMyError*MyErrorErrorerrorerror

返回本身不起作用,因為不是.Go在處理函數接收器時做了一些有用的事情:它會允許你在a上調用任何方法,或者如果接收器是,但它允許你在a上調用方法,如果類型是 - 也就是說,Go不會憑空為你“創建”指針。MyErrorMyError*MyErrorMyError*MyError*MyError*MyError*MyError

如果您要從 中刪除 ,您將告訴 Go 適用于 的任何實例,這意味著兩者都將履行該協定。這就是為什么當您不使用指針接收器時,以下兩者都有效的原因:*func (e* MyError)Error()MyError*MyErrorMyError

func (e MyError) Error() string {}


var _ error = MyError{} // Valid

var _ error = &MyError {}


查看完整回答
反對 回復 2022-08-24
?
紅顏莎娜

TA貢獻1842條經驗 獲得超13個贊

在這種特殊情況下,使用指針不會有任何區別。以下是查看它的一種方式:


在 Go 中,所有變量都按值傳遞。這意味著:


type T struct {...}


func f(value T) {..}


f(t)

上面,作為值傳遞。這意味著當調用時,編譯器會創建的副本并將其傳遞給 。對該副本所做的任何修改都不會影響用于調用 。tftfftf


如果使用指針:


func f(value *T) {...}


f(&t)

在上面,編譯器將創建一個指向 的指針,并將其副本傳遞給 。如果對 進行更改,則這些更改將在 used to call 的實例上進行。換句話說:tffvaluetf


type T struct {

  x int

}


func f(value T) {

   value.x=1

}


func main() {

   t:=T{}

   f(t)

   fmt.Println(t.x)

}

這將打印 0,因為 所做的修改是在 的副本上完成的。ft


func f(value *T) {

   value.x=1

}


func main() {

   t:=T{}

   f(&t)

   fmt.Println(t.x)

}

上面,它會打印1,因為調用會改變。ft


同樣的想法也適用于方法和接收器:


type T struct {

   x int

}


func (t T) f() {

   t.x=1

}


func main() {

   t:=T{}

   t.f()

   fmt.Println(t.x)

}

上述程序將打印 0,因為該方法修改了 的副本。t


func (t *T) f() {

   t.x=1

}


func main() {

   t:=T{}

   t.f()

   fmt.Println(t.x)

}

上面的程序將打印 1,因為該方法的接收器是用指針聲明的,而調用等效于 。t.f()f(&t)


因此,在傳遞參數時使用指針,或者在聲明方法時,如果要修改對象,或者如果復制對象的成本太高,請使用指針。


這只是關于指針參數的故事的一小部分。


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

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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