首先回顧一下go語言值型別和指標型別直接呼叫其值接收者方法和指標接收者方法的區別:
先看乙個例項:
package main
import "fmt"
type i inte***ce
type s struct
func(s s) get()int
func(s *s) set(age int)
func main()
fmt.printf("s1:%d\n",s1.get())
s1.set(20)
fmt.printf("s1:%d\n",s1.get())
s2 := &s{}
fmt.printf("s2:%d\n",s2.get())
s2.set(20)
fmt.printf("s2:%d\n",s2.get())
}
上面例子輸出:
之所以值型別變數和指標型別變數都可以呼叫其值接收者方法和指標接收者方法,僅僅是go語言的語法糖在起作用。
值接收者宣告的方法,呼叫時會使用這個值的乙個副本去執行,而指標接收者在呼叫者會共享呼叫方法時接收者所指向的值,即可以修改指向的值。
接下來我們主要說明值接收者和指標接收者賦值給介面的區別:
先看乙個例項:
package main
import "fmt"
type i inte***ce
type s struct
func(s s) get()int
func(s *s) set(age int)
func main()
fmt.printf("%d\n",s.get())
s.set(20)
fmt.printf("%d\n",s.get())
}
上面例子輸出:
但是把23行改為:
var s i = s{}
編譯將報錯:
大致意思就是:s沒有實現set函式,就沒有實現介面i,所以不能賦值。
表面上看*s也沒有實現get函式,但是*s所指向的值實現了get函式,所以*s也自動擁有get函式,所以實現介面i。s作為值接收者,go無從知道值的原始值是什麼,因為 值接收者 是份拷貝,所以不能影響s。go 會把指標進行隱式轉換得到 value,但反過來則不行。
所以,型別t
變數只有接受者是t
的方法;而型別*t變數
擁有接受者是t
和*t
的方法,換句話,當實現了乙個接收者是值型別的方法,就可以自動生成乙個接收者是對應指標型別的方法,因為兩者都不會影響接收者。但是,當實現了乙個接收者是指標型別的方法,如果此時自動生成乙個接收者是值型別的方法,原本期望對接收者的改變(通過指標實現),現在無法實現,因為值型別會產生乙個拷貝,不會真正影響呼叫者。
值接收者和指標接收者
go語言中有兩種型別的接收者 值型別的接收者和引用型別的接收者 如果使用值接收者宣告方法,呼叫時會使用這個值的乙個副本來執行。當呼叫使用指標接受者宣告的方法時,這個方法會共享呼叫方法時接收者所指向的值。內建型別 值傳遞 數值型別,字串型別,布林型別 引用型別 應用傳遞 切片,對映,通道,介面,函式型...
Go值接收者方法和指標接收者方法
go語言有值型別和指標型別直接呼叫其值接收者方法和指標接收者方法的區別 先看乙個例項 package main import fmt type ifather inte ce type person struct func p person getname string func p person ...
Go介面中的值接收者和指標接收者
先說結論 在實現介面時,應保持接收者定義 結構體定義 斷言型別一致 當方法的接收者定義為值型別時,go 語言編譯器會自動做轉換,所以值型別接收者和指標型別接收者是等價的,編譯不會報錯,執行也都可以呼叫相應方法。package main import fmt type a inte ce type b...