一般來說,我們通常會在實施介面的時候,選擇用值接收者,其實指定指標接收者也是允許的。但是當實施介面的時候使用指標接收者與使用值接收者是由細微差別的。
通過以下的示例來了解一下:
package main
import
"fmt"
type describer inte***ce
type person struct
func
(p person)
describe()
type address struct
func
(a *address)
describe()
func
main()
d1 = p1
d1.describe()
p2 := person
d1 =
&p2 d1.
describe()
var d2 describer
a := address
/* compilation error if the following line is
uncommented
cannot use a (type address) as type describer
in assignment: address does not implement
describer (describe method has pointer
receiver)
*///d2 = a
d2 =
&a //this works since describer inte***ce
//is implemented by address pointer in line 22
d2.describe()
}
從上面的**可以看到,我們定義了兩個結構體,並且讓它們都實現了同樣的介面,也就是describer。在實施address的介面的時候,指定的接收器是指標型別的。首先來看第一種情況,我們定義了兩個person型別的變數p1, p2,並且將它們分別賦值給介面型別變數d1, 前者使用了普通值,後者使用了指標值進行賦值,程式可以正常執行。
而到了第二種情況的時候,首先先定義乙個describer介面型別的變數d2, 然後我們直接將address型別的值賦值給它,此時程式會產生異常,main.go:42: cannot use a (type address) as type describer in assignment: address does not implement describer (describe method has pointer receiver).而當我們將address指標值賦值給變數時,程式不會報錯,而是正常執行。在學習方法定義的時候,帶有指標接收器的方法既可以接收值變數,也可以接收指標變數,但是為何這裡會失敗?
這是因為具有值接收器的方法接受指標和值接收器。在值是任何值或值可以被取消引用的任何值上呼叫值方法都是合法的。當我們在任何已經是具體的指標值或者可以被獲取到位址的值上呼叫指標值接收器方法時都是合法的。將混合型別的值儲存在介面型別的變數中時,無法被位址化,因此對於編譯器來說它無法自動獲取值的位址,所以**失敗了。
值接收者和指標接收者
go語言中有兩種型別的接收者 值型別的接收者和引用型別的接收者 如果使用值接收者宣告方法,呼叫時會使用這個值的乙個副本來執行。當呼叫使用指標接受者宣告的方法時,這個方法會共享呼叫方法時接收者所指向的值。內建型別 值傳遞 數值型別,字串型別,布林型別 引用型別 應用傳遞 切片,對映,通道,介面,函式型...
Go 值接收者和指標接收者 區別
首先回顧一下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 f...
Go值接收者方法和指標接收者方法
go語言有值型別和指標型別直接呼叫其值接收者方法和指標接收者方法的區別 先看乙個例項 package main import fmt type ifather inte ce type person struct func p person getname string func p person ...