一文帶你了解Go語(yǔ)言中接口的使用
接口
在 Go 語(yǔ)言中,接口是一種抽象的類型,是一組方法的集合。接口存在的目的是定義規(guī)范,而規(guī)范的細(xì)節(jié)由其他對(duì)象去實(shí)現(xiàn)。我們來(lái)看一個(gè)例子:
import "fmt"
type Person struct {
Name string
}
func main() {
person := Person{Name: "cmy"}
fmt.Println(person) // {cmy}
}上述代碼定義了結(jié)構(gòu)體 Person ,main 函數(shù)創(chuàng)建了此結(jié)構(gòu)體的變量 person,然后通過(guò) fmt 包里的 Println 函數(shù)打印這個(gè)結(jié)構(gòu)體,打印結(jié)果為 {cmy}。在此基礎(chǔ)上,我們改造一下代碼:
import "fmt"
type Person struct {
Name string
}
func (p Person) String() string {
return fmt.Sprintf("name: %s", p.Name)
}
func main() {
person := Person{Name: "cmy"}
fmt.Println(person) // name: cmy
}新改造的代碼里為結(jié)構(gòu)體 Person 添加一個(gè)結(jié)構(gòu)體方法 String() string,方法的返回結(jié)果是對(duì) name 進(jìn)行格式化,我們?cè)俅蛴∫幌陆Y(jié)構(gòu)體,觀察結(jié)果發(fā)現(xiàn)是 String() 方法返回的值,而不是 {cmy}。 為什么是這樣呢?這是因?yàn)?fmt.Println(T) 函數(shù)的實(shí)現(xiàn)細(xì)節(jié)里,會(huì)對(duì)結(jié)構(gòu)體進(jìn)行判斷,如果結(jié)構(gòu)體實(shí)現(xiàn)了 Stringer 接口,則會(huì)直接打印 String() 方法的返回值。以下是 Stringer 接口的代碼:
type Stringer interface {
String() string
}結(jié)構(gòu)體實(shí)現(xiàn)了這個(gè)接口,也就意味著遵守這個(gè)接口所定義的規(guī)范,fmt.Println(T) 函數(shù)發(fā)現(xiàn)結(jié)構(gòu)體有這個(gè)規(guī)范,因此就會(huì)根據(jù)規(guī)范來(lái)打印信息?;?Stringer 接口,我們來(lái)看看接口的語(yǔ)法格式:
type XXX interface {
// methods
}1、type
接口的聲明,必須以 type 關(guān)鍵字開(kāi)頭。
2、接口名
推薦駝峰式命名法,首字母大寫的方法名可以在包外訪問(wèn),小寫的只能在包內(nèi)訪問(wèn)。
3、interface
接口的標(biāo)識(shí)。
4、接口體
大括號(hào)里面聲明規(guī)范,也就是聲明方法,方法必須具有名字。
接口的實(shí)現(xiàn)
在 Go 語(yǔ)言里,接口的實(shí)現(xiàn)不是基于接口,而是基于方法。如果一個(gè)自定義類型擁有了某個(gè)接口的所有方法,那么這個(gè)自定義類型就實(shí)現(xiàn)這個(gè)接口。接口的實(shí)現(xiàn)在上述的例子中有所體現(xiàn),Person 結(jié)構(gòu)體定義了 String() string 方法,擁有了 Stringer 接口的所有方法,因此實(shí)現(xiàn)了 Stringer 接口。
一個(gè)自定義類型可以實(shí)現(xiàn)多個(gè)接口
type A interface {
a()
}
type B interface {
b()
}
type Person struct {
Name string
}
func (p Person) a() {
}
func (p Person) b() {
}A 接口聲明了 a 方法, B 接口聲明了 b 方法,Person 結(jié)構(gòu)體定義了 a 和 b 兩個(gè)方法,因此 Person 結(jié)構(gòu)體實(shí)現(xiàn)了 A 和 B 兩個(gè)接口。
接口類型變量
一旦接口被定義,它就可以用于聲明變量。
import "fmt"
type A interface {
}
func main() {
var a A
fmt.Println(a) // <nil>
}如果只聲明接口變量,不初始化,變量的值默認(rèn)為 nil,因?yàn)榻涌陬愋蛯?shí)際上是一個(gè)指針。若為接口賦初值,需要選擇一個(gè)合法的值,即被賦值的基類必須實(shí)現(xiàn)這個(gè)接口。
空接口
在 Go 語(yǔ)言里面可以認(rèn)為所有類型實(shí)現(xiàn)了空接口,因?yàn)榭战涌跊](méi)有任何的方法。
import "fmt"
type EmptyInterface interface {
}
func main() {
var a EmptyInterface = 1
var b EmptyInterface = true
var c EmptyInterface = "hello"
var d EmptyInterface = 3.14
var e EmptyInterface = 'c'
fmt.Println(a, b, c, d, e) // 1 true hello 3.14 99
}所有類型都實(shí)現(xiàn)空接口,因此空接口變量可以被賦初值為任意類型的值或變量。
類型斷言
Go 語(yǔ)言支持類型斷言操作,通過(guò)這個(gè)操作,可以還原接口變量的右值(被賦的初值)。類型斷言的語(yǔ)法形式通常為:
v, ok := a.(T)
如果斷言成功,那么 v 的值為接口變量的值,ok 的值為 true;如果斷言失敗,v 的值為 T 類型的零值,ok 的值為 false。
類型斷言變種 type switch
通過(guò) type switch 的方式,可以判斷接口變量屬于哪種動(dòng)態(tài)類型。
import "fmt"
type EmptyInterface interface {
}
func main() {
var a EmptyInterface = 1
switch a.(type) {
case string:
fmt.Println("a 的右值類型為 string")
case int:
fmt.Println("a 的右值類型為 int")
case bool:
fmt.Println("a 的右值類型為 bool")
case float64:
fmt.Println("a 的右值類型為 float64")
}
}小結(jié)
本文先是對(duì)接口的定義進(jìn)行介紹,然后通過(guò)一個(gè)例子,了解了接口其中的一個(gè)應(yīng)用場(chǎng)景和引出接口的語(yǔ)法格式以及實(shí)現(xiàn)的方法,然后介紹了空接口的特點(diǎn)和類型斷言,最后介紹了變種的類型斷言 type switch 的應(yīng)用例子。
到此這篇關(guān)于一文帶你了解Go語(yǔ)言中接口的使用的文章就介紹到這了,更多相關(guān)Go語(yǔ)言接口內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Go設(shè)計(jì)模式原型模式考查點(diǎn)及使用詳解
這篇文章主要為大家介紹了Go設(shè)計(jì)模式原型模式考查點(diǎn)及使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12
Go編寫定時(shí)器與定時(shí)任務(wù)詳解(附第三方庫(kù)gocron用法)
當(dāng)需要每天執(zhí)行定時(shí)任務(wù)的時(shí)候就需要定時(shí)器來(lái)處理了,周期任務(wù),倒計(jì)時(shí)任務(wù),定點(diǎn)任務(wù)等,下面這篇文章主要給大家介紹了關(guān)于Go編寫定時(shí)器與定時(shí)任務(wù)的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-07-07
Go實(shí)現(xiàn)一個(gè)輕量級(jí)并發(fā)任務(wù)調(diào)度器(支持限速)
本文主要介紹了Go實(shí)現(xiàn)一個(gè)輕量級(jí)并發(fā)任務(wù)調(diào)度器(支持限速),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2025-04-04
GO語(yǔ)言中的方法值和方法表達(dá)式的使用方法詳解
這篇文章主要介紹了GO的方法值和方法表達(dá)式的使用方法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-02-02
Go?Singleflight導(dǎo)致死鎖問(wèn)題解決分析
這篇文章主要為大家介紹了Go?Singleflight導(dǎo)致死鎖問(wèn)題解決分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-09-09
golang?使用chromedp獲取頁(yè)面請(qǐng)求日志network
這篇文章主要為大家介紹了golang?使用chromedp獲取頁(yè)面請(qǐng)求日志network方法實(shí)例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-11-11
Go語(yǔ)言中io.Reader和io.Writer的詳解與實(shí)現(xiàn)
在Go語(yǔ)言的實(shí)際編程中,幾乎所有的數(shù)據(jù)結(jié)構(gòu)都圍繞接口展開(kāi),接口是Go語(yǔ)言中所有數(shù)據(jù)結(jié)構(gòu)的核心。在使用Go語(yǔ)言的過(guò)程中,無(wú)論你是實(shí)現(xiàn)web應(yīng)用程序,還是控制臺(tái)輸入輸出,又或者是網(wǎng)絡(luò)操作,不可避免的會(huì)遇到IO操作,使用到io.Reader和io.Writer接口。下面來(lái)詳細(xì)看看。2016-09-09
golang接口實(shí)現(xiàn)調(diào)用修改(值接收者指針接收者)場(chǎng)景詳解
這篇文章主要為大家介紹了golang接口實(shí)現(xiàn)調(diào)用修改值接收者指針接收者示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08

