網站首頁 編程語言 正文
接口
在 Go
語言中,接口是一種抽象的類型,是一組方法的集合。接口存在的目的是定義規范,而規范的細節由其他對象去實現。我們來看一個例子:
import "fmt" type Person struct { Name string } func main() { person := Person{Name: "cmy"} fmt.Println(person) // {cmy} }
上述代碼定義了結構體 Person
,main
函數創建了此結構體的變量 person
,然后通過 fmt
包里的 Println
函數打印這個結構體,打印結果為 {cmy}
。在此基礎上,我們改造一下代碼:
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 }
新改造的代碼里為結構體 Person
添加一個結構體方法 String() string
,方法的返回結果是對 name
進行格式化,我們再打印一下結構體,觀察結果發現是 String()
方法返回的值,而不是 {cmy}
。 為什么是這樣呢?這是因為 fmt.Println(T)
函數的實現細節里,會對結構體進行判斷,如果結構體實現了 Stringer
接口,則會直接打印 String()
方法的返回值。以下是 Stringer 接口的代碼:
type Stringer interface { String() string }
結構體實現了這個接口,也就意味著遵守這個接口所定義的規范,fmt.Println(T)
函數發現結構體有這個規范,因此就會根據規范來打印信息。基于 Stringer
接口,我們來看看接口的語法格式:
type XXX interface { // methods }
1、type
接口的聲明,必須以 type
關鍵字開頭。
2、接口名
推薦駝峰式命名法,首字母大寫的方法名可以在包外訪問,小寫的只能在包內訪問。
3、interface
接口的標識。
4、接口體
大括號里面聲明規范,也就是聲明方法,方法必須具有名字。
接口的實現
在 Go
語言里,接口的實現不是基于接口,而是基于方法。如果一個自定義類型擁有了某個接口的所有方法,那么這個自定義類型就實現這個接口。接口的實現在上述的例子中有所體現,Person
結構體定義了 String() string
方法,擁有了 Stringer
接口的所有方法,因此實現了 Stringer
接口。
一個自定義類型可以實現多個接口
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
結構體定義了 a
和 b
兩個方法,因此 Person
結構體實現了 A
和 B
兩個接口。
接口類型變量
一旦接口被定義,它就可以用于聲明變量。
import "fmt" type A interface { } func main() { var a A fmt.Println(a) // <nil> }
如果只聲明接口變量,不初始化,變量的值默認為 nil
,因為接口類型實際上是一個指針。若為接口賦初值,需要選擇一個合法的值,即被賦值的基類必須實現這個接口。
空接口
在 Go
語言里面可以認為所有類型實現了空接口,因為空接口沒有任何的方法。
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 }
所有類型都實現空接口,因此空接口變量可以被賦初值為任意類型的值或變量。
類型斷言
Go
語言支持類型斷言操作,通過這個操作,可以還原接口變量的右值(被賦的初值)。類型斷言的語法形式通常為:
v, ok := a.(T)
如果斷言成功,那么 v
的值為接口變量的值,ok
的值為 true
;如果斷言失敗,v
的值為 T
類型的零值,ok
的值為 false
。
類型斷言變種 type switch
通過 type switch
的方式,可以判斷接口變量屬于哪種動態類型。
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") } }
小結
本文先是對接口的定義進行介紹,然后通過一個例子,了解了接口其中的一個應用場景和引出接口的語法格式以及實現的方法,然后介紹了空接口的特點和類型斷言,最后介紹了變種的類型斷言 type switch
的應用例子。
原文鏈接:https://juejin.cn/post/7172579057899405326
相關推薦
- 2022-08-13 SpringSecurity+JWT實現認證及授權詳細步驟
- 2023-07-17 uniapp 用forEach循環遍歷數組
- 2022-07-21 css實現水平居中和垂直居中,清除浮動
- 2022-04-23 論C++的lambda是函數還是對象_C 語言
- 2022-09-03 PyQt5實現tableWidget?居中顯示_python
- 2021-12-04 Linux超詳細gcc升級全過程_Linux
- 2021-12-20 ES6 Number 數值的擴展 0.1 + 0.2 === 0.3 居然是false
- 2022-09-27 WIN10使用IIS部署ftp服務器詳細教程_FTP服務器
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支