1. 程式人生 > 其它 >interface介面_Golang | 既是介面又是型別,interface是什麼神仙用法?

interface介面_Golang | 既是介面又是型別,interface是什麼神仙用法?

技術標籤:interface介面

點選上方藍字,關注並星標,和我一起學技術。

4616a0bb584c8da572943c976e13a967.png

今天是golang專題的第12篇文章,我們來繼續聊聊interface的使用。

在上一篇文章當中我們介紹了面向物件的一些基本概念,以及golang當中interface和多型的實現方法。今天我們繼續來介紹interface當中其他的一些方法。

萬能型別interface

在Java以及其他語言當中介面是一種寫法規範,而在golang當中,interface其實也是一種值,它可以像是值一樣傳遞。並且在它的底層,它其實是一個值和型別的元組。

這裡我們來看下golang官方文件當中的一個例子:

packagemain

import(
"fmt"
"math"
)

typeIinterface{
M()
}

typeTstruct{
Sstring
}

func(t*T)M(){
fmt.Println(t.S)
}

typeFfloat64

func(fF)M(){
fmt.Println(f)
}

funcmain(){
variI

i=&T{"Hello"}
describe(i)
i.M()

i=F(math.Pi)
describe(i)
i.M()
}

funcdescribe(iI){
fmt.Printf("(%v,%T)\n",i,i)
}

在上面的程式碼當中定義了一個叫做describe的方法,在這個方法當中我們輸出了兩個值,一個是介面i對應的值,另一個是介面i的型別

我們輸出的結果如下:

3ff404e3281d4362f6fe22aefb55bf5f.png

可以看到介面當中既儲存了對應的結構體的例項的資訊,也儲存了結構體的型別。因此interface可以理解成一種特殊的型別。

實際上也的確如此,我們可以把interface理解成一種萬能資料型別,它可以接收任何型別的值。我們看下下面這種用法:

vara1interface{}=1
vara2interface{}="abc"
list:=make([]interface{},0)
list=append(list,a1)
list=append(list,a2)
fmt.Println(list)

在程式碼當中我們建立了一個interface{}型別的slice,它可以接收任何型別的值和例項。另外我們用interface{}這個型別也可以接收任何結構體的值。這裡可能會有些迷惑,其實很容易想明白。interface表示一種型別,可以接收任何實現了interface當中規定的方法的型別的值。當我們定義inteface{}的時候,其實是定義了空的interface

,相當於不需要實現任何方法的空interface,所以任何型別都可以接收,這也就是它成為萬能型別的原因。

我們接收當然沒有問題,問題是我們怎麼使用這些interface型別的值呢?

一種方法是我們可以判斷一個interface的變數型別。判斷的方法非常簡單,我們在interface的變數後面用.(type)的方法來判斷。它和map的key值判斷一樣,會返回一個值和bool型別的標記。我們可以通過這個標記判斷這個型別是否正確。

ifv,ok:=a1.(int);ok{
fmt.Println(v)
}

如果型別比較多的話使用switch也是可以的:

switchv:=i.(type){
caseint:
fmt.Println("int")
casestring:
fmt.Println("string")
}