這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
golang介面
介面,姑且就稱之為定義了一系列(也可能是空的)方法,但是又沒有實現這些方法的一種結構體。
有時候,在糾結,介面類型的變數,到底是什麼類型了?帶著這個問題,來實操一下。
首先定義兩個個介面:
type YourType interface { SayHi(str string)}type HeType interface { SayHi(str string) SayBye(str string)}
上邊是兩個介面,YourYype介面中定義了一個SayHi方法。HeType定義了SayHi方法與SayBye方法。
下邊再來定義一個類實現YourType介面。
type youknow struct {}func (t youknow) SayHi(str string) { fmt.Println("hi " + str)}
上邊的youknow就實現了YourType方法。
接著再來定義一個類,實現HeType介面,HeType介面中的SayHi方法與YourType介面中的SayHi方法一樣,也就是說youknow實現了HeType介面的SayHi方法,但是沒有實現SayBye方法,那麼接下來用過匿名組合的方式,實現SayBye介面,代碼如下:
type dknow struct { youknow}func (t *dknow) SayBye(str string) { fmt.Println("bye bye " + str + ".see you tomorrow.")}
通過匿名組合,上邊的dknow就實現了HeType介面,匿名組合,是不是很好用,贊一個。
下邊來通過代碼示範結果。
func main() { var myouknow YourType = youknow{} myouknow.SayHi("demo") var mdknow HeType = new(dknow) mdknow.SayBye("demo")}
上邊先定義了一個介面類型的變數myouknow,賦值時,使用的youknow的結構體類型。
在定義HeType介面類型的變數mdknow時,採用的是指標類型的dknow
為什麼會出現兩種不同的情況了,也就是說介面既可以是struct,又可以是Ptr,那麼怎麼去判斷,什麼時候該給struct類型,什麼時候又改給Ptr類型了。
原則:
1. 看實現介面的類,在實現介面方法時,指向的是指標,還是非指標。youknow類在實現介面YourType時,他的方法SayHi是指向非指標的(專業術語不太會,姑且就這麼描述了,不標準的地方請諒解,詞可達意,無礙傳播知識的要求寫的文章,下同)。所以將youknow類執行個體化賦值給介面時,需要採用struct類型。
2. dknow類在實現HeType介面時,將SayBye方法指向了指標類型,所以在執行個體化dknow類賦值給介面時,需要使用Ptr類型賦值給介面變數。
3. dknow組合的youknow實現了SayHi方法,指向了Struct類型,自己實現的SayBye,又指向了Ptr,這種情況怎麼算?答案是,SayHi指向的非指標對象,golang會自動產生一個指向指標的SayHi方法,那麼dknow不就有指向指標的SayHi域SayBye兩個方法了嘛,所以dknow就實現了HeType介面了。
4. 那將dknow類中的SayBye方法不指向指標,將youknow類中的SayHi指向指標,還能這樣賦值嗎?答案是,YourType介面類型的變數需要用Ptr賦值,HeType介面類型的變數,也需要用Ptr賦值。也就是說指向Struct的方法,會自動產生指向Ptr的方法,反之,不會。
package mainimport "fmt"type YourType interface { SayHi(str string)}type HeType interface { SayHi(str string) SayBye(str string)}type youknow struct {}type dknow struct { youknow}func (t youknow) SayHi(str string) { fmt.Println("hi " + str)}func (t *dknow) SayBye(str string) { fmt.Println("bye bye " + str + ".see you tomorrow.")}func main() { var myouknow YourType = youknow{} myouknow.SayHi("demo") var mdknow HeType = new(dknow) mdknow.SayBye("demo") mdknow.SayHi("he type")}