Go語言接口不同于其他語言。在Go語言中,該接口是一種自定義類型,用于指定一組一個(gè)或多個(gè)方法簽名,并且該接口是抽象的,因此不允許您創(chuàng)建該接口的實(shí)例。但是您可以創(chuàng)建接口類型的變量,并且可以為該變量分配具有接口所需方法的具體類型值。換句話說,接口既是方法的集合,也是自定義類型。
在Go語言中,您可以使用以下語法創(chuàng)建接口:
type interface_name interface{
//方法簽名
}例如:
//創(chuàng)建一個(gè)接口
type myinterface interface{
// 方法
fun1() int
fun2() float64
}此處,接口名稱包含在type和interface關(guān)鍵字之間,方法簽名包含在花括號(hào)之間。
在Go語言中,為了實(shí)現(xiàn)接口,必須實(shí)現(xiàn)接口中聲明的所有方法。go語言接口是隱式實(shí)現(xiàn)的。與其他語言一樣,它不包含實(shí)現(xiàn)接口的任何特定關(guān)鍵字。如下例所示:

// Golang程序說明如何
//實(shí)現(xiàn)接口
package main
import "fmt"
//創(chuàng)建一個(gè)接口
type tank interface {
// 方法
Tarea() float64
Volume() float64
}
type myvalue struct {
radius float64
height float64
}
//實(shí)現(xiàn)方法
//桶的(Tank)接口
func (m myvalue) Tarea() float64 {
return 2*m.radius*m.height + 2*3.14*m.radius*m.radius
}
func (m myvalue) Volume() float64 {
return 3.14 * m.radius * m.radius * m.height
}
func main() {
// 訪問使用桶的接口
var t tank
t = myvalue{10, 14}
fmt.Println("桶的面積 :", t.Tarea())
fmt.Println("桶的容量:", t.Volume())
}輸出:
桶的面積 : 908 桶的容量: 4396
接口的零值為nil。
當(dāng)接口包含零個(gè)方法時(shí),此類接口稱為空接口。因此,所有類型都實(shí)現(xiàn)空接口。
語法:
interface{}接口類型:該接口有兩種類型,一種是靜態(tài)的,另一種是動(dòng)態(tài)的。靜態(tài)類型是接口本身,例如下面示例中的tank。但是接口沒有靜態(tài)值,所以它總是指向動(dòng)態(tài)值。
接口類型的變量,其中包含實(shí)現(xiàn)接口的類型的值,因此該類型的值稱為動(dòng)態(tài)值,而該類型是動(dòng)態(tài)類型。又稱具體值和具體類型。
//說明Go程序的概念
//動(dòng)態(tài)值和類型
package main
import "fmt"
//創(chuàng)建接口
type tank interface {
// 方法
Tarea() float64
Volume() float64
}
func main() {
var t tank
fmt.Println("tank interface值為: ", t)
fmt.Printf("tank 的類型是: %T ", t)
}輸出:
tank interface值為: <nil> tank 的類型是: <nil>
在上面的示例中,有一個(gè)名為tank的接口。在此示例中,fmt.Println("tank interface值為: ", t) 語句返回該接口的動(dòng)態(tài)值,而 fmt.Printf("tank 的類型是: %T ", t) 語句返回該接口的動(dòng)態(tài)類型,即nil,因?yàn)檫@里的接口不知道誰在實(shí)現(xiàn)它。
類型斷言:在Go語言中,類型斷言是應(yīng)用于接口值的操作。換句話說,類型斷言是提取接口值的過程。
語法:
a.(T)
在這里,a是接口的值或表達(dá)式,T是也稱為類型斷言的類型。類型斷言用于檢查其操作數(shù)的動(dòng)態(tài)類型是否匹配已斷言的類型。如果T是具體類型,則類型斷言檢查a的給定動(dòng)態(tài)類型是否等于T,這里,如果檢查成功進(jìn)行,則類型斷言返回a的動(dòng)態(tài)值。否則,如果檢查失敗,則操作將出現(xiàn)panic異常。如果T是接口類型,則類型斷言檢查滿足T的給定動(dòng)態(tài)類型,這里,如果檢查成功進(jìn)行,則不提取動(dòng)態(tài)值。
//類型斷言
package main
import "fmt"
func myfun(a interface{}) {
//提取a的值
val := a.(string)
fmt.Println("值為: ", val)
}
func main() {
var val interface {
} = "nhooo"
myfun(val)
}輸出:
值為: nhooo
在上面的示例中,如果將val:= a。(string)語句更改為val:= a。(int),則程序會(huì)拋出panic異常。因此,為了避免此問題,我們使用以下語法:
value, ok := a.(T)
在這里,如果a的類型等于T,則該值包含a的動(dòng)態(tài)值,并且ok將設(shè)置為true。并且如果a的類型不等于T,則ok設(shè)置為false并且value包含零值,并且程序不會(huì)拋出panic異常。如下面的程序所示:
package main
import "fmt"
func myfun(a interface{}) {
value, ok := a.(float64)
fmt.Println(value, ok)
}
func main() {
var a1 interface {
} = 98.09
myfun(a1)
var a2 interface {
} = "nhooo"
myfun(a2)
}輸出:
98.09 true 0 false
類型判斷:在Go接口中,類型判斷用于將接口的具體類型與case語句中提供的多種類型進(jìn)行比較。它與類型聲明類似,只是有一個(gè)區(qū)別,即大小寫指定類型,而不是值。您還可以將類型與接口類型進(jìn)行比較。如下例所示:
package main
import "fmt"
func myfun(a interface{}) {
//使用類型判斷
switch a.(type) {
case int:
fmt.Println("類型: int,值:", a.(int))
case string:
fmt.Println("\n類型: string,值: ", a.(string))
case float64:
fmt.Println("\n類型: float64,值: ", a.(float64))
default:
fmt.Println("\n類型未找到")
}
}輸出:
類型: string,值: nhooo 類型: float64,值: 67.9 類型未找到
接口的使用:當(dāng)您想要在其中傳遞不同類型的參數(shù)的方法或函數(shù)中時(shí),可以使用接口,就像Println()函數(shù)一樣?;蛘撸?dāng)多種類型實(shí)現(xiàn)同一接口時(shí),也可以使用接口。