我的在線博客:http://golang.iswbm.com
我的 Github:github.com/iswbm/GolangCodingTime
1. 對方法的調(diào)用限制
接口是一組固定的方法集,由于靜態(tài)類型的限制,接口變量有時僅能調(diào)用其中特定的一些方法。
請看下面這段代碼
package main
import "fmt"
type Phone interface {
call()
}
type iPhone struct {
name string
}
func (phone iPhone)call() {
fmt.Println("Hello, iPhone.")
}
func (phone iPhone)send_wechat() {
fmt.Println("Hello, Wechat.")
}
func main() {
var phone Phone
phone = iPhone{name:"ming's iphone"}
phone.call()
phone.send_wechat()
}
我定義了一個 Phone 的接口,只要求實現(xiàn) call 方法即可,也就是只要能打電話的設(shè)備就是一個電話(好像是一句沒用的廢話)。
然后再定義了一個 iPhone 的結(jié)構(gòu)體,該結(jié)構(gòu)體接收兩個方法,一個是打電話( call 函數(shù)),一個是發(fā)微信(send_wechat 函數(shù))。
最后一步是關(guān)鍵,我們定義了一個 Phone 接口類型的 phone 對象,該對象的內(nèi)容是 iPhone 結(jié)構(gòu)體。然后我們調(diào)用該對象的 call 方法,一切正常。
但是當(dāng)你調(diào)用 phone.send_wechat
方法,程序會報錯,提示我們 Phone 類型的方法沒有 send_wechat 的字段或方法。
# command-line-arguments
./demo.go:30:10: phone.send_wechat undefined (type Phone has no field or method send_wechat)
原因也很明顯,因為我們的phone對象顯示聲明為 Phone 接口類型,因此 phone調(diào)用的方法會受到此接口的限制。
那么如何讓 phone 可以調(diào)用 send_wechat 方法呢?
答案是可以不顯示的聲明為 Phone接口類型 ,但要清楚 phone 對象實際上是隱式的實現(xiàn)了 Phone 接口,如此一來,方法的調(diào)用就不會受到接口類型的約束。
修改 main 方法成如下
func main() {
phone := iPhone{name:"ming's iphone"}
phone.call()
phone.send_wechat()
}
運行后,一切正常,沒有報錯。
Hello, iPhone.
Hello, Wechat.
2. 調(diào)用函數(shù)時的隱式轉(zhuǎn)換
Go 語言中的函數(shù)調(diào)用都是值傳遞的,變量會在方法調(diào)用前進(jìn)行類型轉(zhuǎn)換。
比如下面這段代碼
import (
"fmt"
)
func printType(i interface{}) {
switch i.(type) {
case int:
fmt.Println("參數(shù)的類型是 int")
case string:
fmt.Println("參數(shù)的類型是 string")
}
}
func main() {
a := 10
printType(a)
}
如果你運行后,會發(fā)現(xiàn)一切都很正常
參數(shù)的類型是 int
但是如果你把函數(shù)內(nèi)的內(nèi)容搬到到外面來
package main
import "fmt"
func main() {
a := 10
switch a.(type) {
case int:
fmt.Println("參數(shù)的類型是 int")
case string:
fmt.Println("參數(shù)的類型是 string")
}
}
就會有意想不到的結(jié)果,居然報錯了。
# command-line-arguments
./demo.go:9:5: cannot type switch on non-interface value a (type int)
這個操作會讓一個新人摸不著頭腦,代碼邏輯都是一樣的,為什么一個不會報錯,一個會報錯呢?
原因其實很簡單。
當(dāng)一個函數(shù)接口 interface{} 空接口類型時,我們說它可以接收什么任意類型的參數(shù)(江湖上稱之為無招勝有招)。
當(dāng)你使用這種寫法時,Go 會默默地為我們做一件事,就是把傳入函數(shù)的參數(shù)值(注意:Go 語言中的函數(shù)調(diào)用都是值傳遞的)的類型隱式的轉(zhuǎn)換成 interface{} 類型。
如何進(jìn)行接口類型的顯示轉(zhuǎn)換
上面了解了函數(shù)中 接口類型的隱式轉(zhuǎn)換后,你的心里可能開始有了疑問了,難道我使用類型斷言,只能通過一個接收空接口類型的函數(shù)才能實現(xiàn)嗎?
答案當(dāng)然是 No.
如果你想手動對其進(jìn)行類型轉(zhuǎn)換,可以像下面這樣子,就可以將變量 a 的靜態(tài)類型轉(zhuǎn)換為 interface{} 類型然后賦值給 b (此時 a 的靜態(tài)類型還是 int,而 b 的靜態(tài)類型為 interface{})
var a int = 25
b := interface{}(a)
知道了方法后,將代碼修改成如下:
package main
import "fmt"
func main() {
a := 10
switch interface{}(a).(type) {
case int:
fmt.Println("參數(shù)的類型是 int")
case string:
fmt.Println("參數(shù)的類型是 string")
}
}
運行后,一切正常。
參數(shù)的類型是 int
3. 類型斷言中的隱式轉(zhuǎn)換
上面我們知道了,只有靜態(tài)類型為接口類型的對象才可以進(jìn)行類型斷言。
而當(dāng)類型斷言完成后,會返回一個靜態(tài)類型為你斷言的類型的對象,也就是說,當(dāng)我們使用了類型斷言,Go 實際上又會默認(rèn)為我們進(jìn)行了一次隱式的類型轉(zhuǎn)換。
驗證方法也很簡單,使用完一次類型斷言后,對返回的對象再一次使用類型斷言,Goland 立馬就會提示我們新對象 b 不是一個接口類型的對象,不允許進(jìn)行類型斷言。

總結(jié)
到此這篇關(guān)于Go 語言中關(guān)于接口的三個"潛規(guī)則"的文章就介紹到這了,更多相關(guān)go語言接口內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
您可能感興趣的文章:- 如何判斷Golang接口是否實現(xiàn)的操作
- golang接口IP限流,IP黑名單,IP白名單的實例
- GO語言gin框架實現(xiàn)管理員認(rèn)證登陸接口
- Go語言使用swagger生成接口文檔的方法
- go語言實現(xiàn)接口查詢