在面向對象的領域里,接口一般這樣定義:**接口定義一個對象的行為**
Go語言提倡面向接口編程
特性:
* 接口是一個或多個方法簽名的集合;
* 任何類型的方法集中只要擁有該接口'對應的全部方法'簽名,就表示它 "實現" 了該接口,無須在該類型上顯式聲明實現了哪個接口,這稱為Structural Typing;
* 接口只有方法聲明,沒有實現,沒有數據字段;
* 接口可以匿名嵌入其他接口,或嵌入到結構中;
* 對象賦值給接口時,會發生拷貝,而接口內部存儲的是指向這個復制品的指針,既無法修改復制品的狀態,也無法獲取指針;
* 只有當接口存儲的類型和對象都為nil時,接口才等于nil;
* 接口調用不會做receiver的自動轉換;
* 接口同樣支持匿名字段方法;
* 接口也可實現類似OOP中的多態;
* 空接口可以作為任何類型數據的容器;
* 一個類型可實現多個接口;
## 1.語法
在 Go 語言中,接口就是方法簽名(Method Signature)的集合
~~~
//interface definition
type interfaceName interface {
FindVowels() []rune
}
~~~
在Go語言中接口(interface)是一種類型,一種抽象的類型
接口命名習慣以 er 結尾;
## 2.空接口
沒有包含方法的接口稱為空接口。空接口表示為`interface{}`。由于空接口沒有方法,因此所有類型都實現了空接口
## 3.接口零值
接口的零值是`nil`。對于值為`nil`的接口,其底層值(Underlying Value)和具體類型(Concrete Type)都為`nil`
~~~go
type Describer interface {
Describe()
}
func main() {
var d1 Describer
if d1 == nil {
fmt.Printf("d1 is nil and has type %T value %v\n", d1, d1)
}
}
~~~
## 6.實現接口:指針接受者與值接受者
* go采用duck type方式實現接口
* 使用值接受者聲明的方法,既可以用值來調用,也能用指針調用
* 對于使用指針接受者的方法,用一個指針或者一個可取得地址的值來調用都是合法的
* 類型可以實現多個接口;
* 一個類型如果定義了接口的所有方法,那它就隱式地實現了該接口;
~~~
package main
import (
"fmt"
)
type SalaryCalculator interface {
DisplaySalary()
}
type LeaveCalculator interface {
CalculateLeavesLeft() int
}
type Employee struct {
firstName string
lastName string
basicPay int
pf int
totalLeaves int
leavesTaken int
}
func (e Employee) DisplaySalary() {
fmt.Printf("%s %s has salary $%d", e.firstName, e.lastName, (e.basicPay + e.pf))
}
func (e Employee) CalculateLeavesLeft() int {
return e.totalLeaves - e.leavesTaken
}
func main() {
e := Employee {
firstName: "Naveen",
lastName: "Ramanathan",
basicPay: 5000,
pf: 200,
totalLeaves: 30,
leavesTaken: 5,
}
var s SalaryCalculator = e
s.DisplaySalary()
var l LeaveCalculator = e
fmt.Println("\nLeaves left =", l.CalculateLeavesLeft())
}
~~~
### 接口嵌套
~~~
type SalaryCalculator interface {
DisplaySalary()
}
type LeaveCalculator interface {
CalculateLeavesLeft() int
}
type EmployeeOperations interface {
SalaryCalculator
LeaveCalculator
}
~~~
## 8.接口變量的內存布局
我們可以把接口看作內部的一個元組`(type, value)`。`type`是接口底層的具體類型(Concrete Type),而`value`是具體類型的值

## 9.接口最佳實踐
* 傾向于使用小的接口定義,很多接口只包含一個方法;
* 較大的接口定義,可以由多個小接口定義組合而成;
* 只依賴必要功能的最小接口
<br>
*****
與其他編程語言的差異:
接口為非侵入式,實現不依賴與接口定義;
- 概述
- go語言基礎特性
- Go語言聲明
- Go項目構建及編譯
- go command
- 程序設計原則
- Go基礎
- 變量
- 常量
- iota
- 基本類型
- byte和rune類型
- 類型定義和類型別名
- 數組
- string
- 高效字符串連接
- string底層原理
- 運算符
- new
- make
- 指針
- 下劃線 & import
- 語法糖
- 簡短變量申明
- 流程控制
- ifelse
- switch
- select
- select實現原理
- select常見案例
- for
- range
- range實現原理
- 常見案例
- range陷阱
- Goto&Break&Continue
- Go函數
- 函數
- 可變參數函數
- 高階函數
- init函數和main函數
- 匿名函數
- 閉包
- 常用內置函數
- defer
- defer常見案例
- defer規則
- defer與函數返回值
- defer實現原理
- defer陷阱
- 數據結構
- slice
- slice內存布局
- slice&array
- slice底層實現
- slice陷阱
- map
- Map實現原理
- 集合
- List
- Set
- 線程安全數據結構
- sync.Map
- Concurrent Map
- 面向對象編程
- struct
- 匿名結構體&匿名字段
- 嵌套結構體
- 結構體的“繼承”
- struct tag
- 行為方法
- 方法與函數
- type Method Value & Method Expressions
- interface
- 類型斷言
- 多態
- 錯誤機制
- error
- 自定義錯誤
- panic&recover
- reflect
- reflect包
- 應用示例
- DeepEqual
- 反射-fillObjectField
- 反射-copyObject
- IO
- 讀取文件
- 寫文件
- bufio
- ioutil
- Go網絡編程
- tcp
- tcp粘包
- udp
- HTTP
- http服務
- httprouter
- webSocket
- go并發編程
- Goroutine
- thread vs goroutine
- Goroutine任務取消
- 通過channel廣播實現
- Context
- Goroutine調度機制
- goroutine調度器1.0
- GMP模型調度器
- 調度器竊取策略
- 調度器的生命周期
- 調度過程全解析
- channel
- 無緩沖的通道
- 緩沖信道
- 單向信道
- chan實現原理
- 共享內存并發機制
- mutex互斥鎖
- mutex
- mutex原理
- mutex模式
- RWLock
- 使用信道處理競態條件
- WaitGroup
- 工作池
- 并發任務
- once運行一次
- 僅需任意任務完成
- 所有任務完成
- 對象池
- 定時器Timer
- Timer
- Timer實現原理
- 周期性定時器Ticker
- Ticker對外接口
- ticker使用場景
- ticker實現原理
- ticker使用陷阱
- 包和依賴管理
- package
- 依賴管理
- 測試
- 單元測試
- 表格測試法
- Banchmark
- BDD
- 常用架構模式
- Pipe-filter pattern
- Micro Kernel
- JSON
- json-內置解析器
- easyjson
- 性能分析
- gc
- 工具類
- fmt
- Time
- builtin
- unsafe
- sync.pool
- atomic
- flag
- runtime
- strconv
- template