go語言接口轉換 go語言接口詳解
go語言接口轉換 go語言接口詳解
轉載
一、接口
1.1 接口類型
在Go語言中接口(interface)是一種類型,一種抽象的類型。
interface是一組method的集合,是duck-type programming的一種體現。接口做的事情就像是定義一個協議(規則),只要一臺機器有洗衣服和甩干的功能,我就稱它為洗衣機。不關心屬性(數據),只關心行為(方法)。
為了保護你的Go語言職業生涯,請牢記接口(interface)是一種類型。
1.2 為什么要使用接口
上面的代碼中定義了貓和狗,然后它們都會叫,你會發現main函數中明顯有重復的代碼,如果我們后續再加上豬、青蛙等動物的話,我們的代碼還會一直重復下去。那我們能不能把它們當成“能叫的動物”來處理呢?
1.3 接口的定義
Go語言提倡面向接口編程。
每個接口由數個方法組成,接口的定義格式如下:
其中:
- 接口名:使用
type將接口定義為自定義的類型名。Go語言的接口在命名時,一般會在單詞后面添加er,如有寫操作的接口叫Writer,有字符串功能的接口叫Stringer等。接口名最好要能突出該接口的類型含義。 - 方法名:當方法名首字母是大寫且這個接口類型名首字母也是大寫時,這個方法可以被接口所在的包(package)之外的代碼訪問。
- 參數列表、返回值列表:參數列表和返回值列表中的參數變量名可以省略。
舉個例子:
當你看到這個接口類型的值時,你不知道它是什么,唯一知道的就是可以通過它的Write方法來做一些事情。
1.4 實現接口的條件
一個對象只要全部實現了接口中的方法,那么就實現了這個接口。換句話說,接口就是一個需要實現的方法列表。
我們來定義一個Sayer接口:
定義dog和cat兩個結構體:
因為Sayer接口里只有一個say方法,所以我們只需要給dog和cat 分別實現say方法就可以實現Sayer接口了。
接口的實現就是這么簡單,只要實現了接口中的所有方法,就實現了這個接口。
1.5 接口類型變量
那實現了接口有什么用呢?
接口類型變量能夠存儲所有實現了該接口的實例。 例如上面的示例中,Sayer類型的變量能夠存儲dog和cat類型的變量。
1.6 值接收者和指針接收者實現接口的區別
使用值接收者實現接口和使用指針接收者實現接口有什么區別呢?接下來我們通過一個例子看一下其中的區別。
我們有一個Mover接口和一個dog結構體。
1.6.1 值接收者實現接口
此時實現接口的是dog類型:
從上面的代碼中我們可以發現,使用值接收者實現接口之后,不管是dog結構體還是結構體指針*dog類型的變量都可以賦值給該接口變量。因為Go語言中有對指針類型變量求值的語法糖,dog指針fugui內部會自動求值*fugui。
1.6.2 指針接收者實現接口
同樣的代碼我們再來測試一下使用指針接收者有什么區別:
此時實現Mover接口的是*dog類型,所以不能給x傳入dog類型的wangcai,此時x只能存儲*dog類型的值。
1.6.3 測試題
注意:這是一道你需要回答“能”或者“不能”的題!
首先請觀察下面的這段代碼,然后請回答這段代碼能不能通過編譯?
1.7 類型與接口的關系
1.7.1 一個類型實現多個接口
一個類型可以同時實現多個接口,而接口間彼此獨立,不知道對方的實現。 例如,狗可以叫,也可以動。我們就分別定義Sayer接口和Mover接口,如下: Mover接口。
dog既可以實現Sayer接口,也可以實現Mover接口。
1.7.2 多個類型實現同一接口
Go語言中不同的類型還可以實現同一接口 首先我們定義一個Mover接口,它要求必須由一個move方法。
例如狗可以動,汽車也可以動,可以使用如下代碼實現這個關系:
這個時候我們在代碼中就可以把狗和汽車當成一個會動的物體來處理了,不再需要關注它們具體是什么,只需要調用它們的move方法就可以了。
上面的代碼執行結果如下:
并且一個接口的方法,不一定需要由一個類型完全實現,接口的方法可以通過在類型中嵌入其他類型或者結構體來實現。
1.8 接口嵌套
接口與接口間可以通過嵌套創造出新的接口。
嵌套得到的接口的使用與普通接口一樣,這里我們讓cat實現animal接口:
1.9.1 空接口的定義
空接口是指沒有定義任何方法的接口。因此任何類型都實現了空接口。
空接口類型的變量可以存儲任意類型的變量。
1.9.2 空接口的應用
空接口作為函數的參數
使用空接口實現可以接收任意類型的函數參數。
空接口作為map的值
使用空接口實現可以保存任意值的字典。
1.10 類型斷言
空接口可以存儲任意類型的值,那我們如何獲取其存儲的具體數據呢?
1.10.1 接口值
一個接口的值(簡稱接口值)是由一個具體類型和具體類型的值兩部分組成的。這兩部分分別稱為接口的動態類型和動態值。
我們來看一個具體的例子:
請看下圖分解:


想要判斷空接口中的值這個時候就可以使用類型斷言,其語法格式:
其中:
- x:表示類型為
interface{}的變量 - T:表示斷言
x可能是的類型。
該語法返回兩個參數,第一個參數是x轉化為T類型后的變量,第二個值是一個布爾值,若為true則表示斷言成功,為false則表示斷言失敗。
舉個例子:
上面的示例中如果要斷言多次就需要寫多個if判斷,這個時候我們可以使用switch語句來實現:
因為空接口可以存儲任意類型值的特點,所以空接口在Go語言中的使用十分廣泛。
關于接口需要注意的是,只有當有兩個或兩個以上的具體類型必須以相同的方式進行處理時才需要定義接口。不要為了接口而寫接口,那樣只會增加不必要的抽象,導致不必要的運行時損耗。

浙公網安備 33010602011771號