目錄
簡介
結構體
宣告/定義
實作與使用
實作
多介面實作
介面繼承
空介面
結構體切片排序
介面和繼承比較
注意項
全部代碼
截圖
參考
簡介
Go 語言中的介面是一種內置的型別,它定義了一組方法的簽名,體現了程式設計的高內聚低耦合的特點,本篇文章會介紹介面及基本使用,下篇文章介紹型別斷言,
結構體
定義Monkey結構體,具有climb方法,
type Monkey struct {
Name string
}
func (m *Monkey)climb(){
fmt.Println(m.Name,"會爬樹...")
}
定義WuKong結構體,包含Monkey和Tool屬性,
type WuKong struct {
Monkey
Tool string
}
宣告/定義
定義介面模板如下:
/* 定義介面 */
type interface_name interface {
method_name1([parameter list]) (return_type)
method_name2 ([parameter list]) (return_type)
...
method_namen([parameter list]) (return_type)
}
代碼
定義Flyable介面
type Flyable interface {
Fly()
}
實作與使用
實作
實作了介面的所有方法,就是實作了該介面,不需要顯示指明是哪個介面,即隱式實作,
func (w *WuKong) Fly() {
fmt.Println("筋斗云,來...")
}
鴨子型別
鴨子型別(duck typing)是動態型別的一種風格,例如,Python語言中比較常見,在這種風格中,一個物件有效的語意,不是由繼承自特定的類或實作特定的介面,而是由"當前方法和屬性集合"決定,
而在Go中,就是由當前結構體的方法集合決定當前結構體是否實作了某個介面,WuKong可以飛,而Monkey不可以飛,WuKong在繼承Monkey的基礎上,擴展了自己的功能,
多介面實作
再定義一個介面
type Swimmable interface {
Swim()
}
實作
func (w *WuKong) Swim() {
fmt.Println("老龍王,俺老孫的金箍棒呢?")
}
WuKong結構體就實作了上面的兩個介面,
介面繼承
再定義一個介面Skills,繼承前面的兩個介面,并添加新的方法Change
type Skills interface {
Flyable
Swimmable
Change()
}
實作
func (w *WuKong) Change() {
fmt.Println("看我72變...")
}
至此, WuKong結構體實作了四個介面,為什么是四個呢?因為還有下面這一個
空介面
type Null interface {
}
如你所見,什么方法也沒有,即每個結構體都實作了空介面,都可以賦值給空介面,這在排序,后面型別斷言等部分都很有用,
結構體切片排序
func Sort(data Interface)
Sort,本地排序data,無回傳,它呼叫1次data.Len確定長度,呼叫O(n*log(n))次data.Less和data.Swap,底層使用的是快排,感興趣的朋友可以看看快排源代碼,本函式不能保證排序的穩定性(即不保證相等元素的相對次序不變),
// Sort sorts data.
// It makes one call to data.Len to determine n and O(n*log(n)) calls to
// data.Less and data.Swap. The sort is not guaranteed to be stable.
func Sort(data Interface) {
n := data.Len()
quickSort(data, 0, n, maxDepth(n))
}
Interface介面
type Interface interface {
// Len is the number of elements in the collection.
Len() int
// Less reports whether the element with index i must sort before the element with index j.
// See Float64Slice.Less for a correct implementation for floating-point values.
Less(i, j int) bool
// Swap swaps the elements with indexes i and j.
Swap(i, j int)
}
既然這是一個介面,只要我們實作了Len、Less、Swap方法即可傳參,進行排序,
我們就用Monkey結構體的切片實作一下這個介面,
type MonkeySlice []Monkey
//--------實作Len--------
func (m MonkeySlice) Len() int{
return len(m)
}
//---------實作Less---------
func (m MonkeySlice) Less(i,j int) bool {
return m[i].Name < m[j].Name
}
//----------實作Swap---------
func (m MonkeySlice) Swap(i,j int){
m[i],m[j] = m[j],m[i]
}
使用
monkeys := MonkeySlice{{"峨眉猴"},{"齊天大圣"},{"金絲猴"},{"六耳獼猴"},{"孫悟空"}}
sort.Sort(monkeys)
fmt.Println(monkeys)
介面和繼承比較
- 當A結構體繼承了B結構體,那么A結構體就自動的繼承了B結構體的欄位和方法,并且可以直接使用
- 當A結構體需要擴展功能,同時不希望去破壞繼承關系,則可以去實作某個介面即可,
- 介面是對繼承的補充,是like和is的區別
- 繼承解決代碼的復用性和可維護性
- 介面更加靈活,一定程度上實作了解耦
注意項
- 介面不能創建實體,介面可以指向實作了介面的結構體實體
- 結構體必須實作所有介面的方法才可以說實作了該介面
- 介面默認是指標型別,沒有初始化會輸出nil
- 空介面可以接收任何型別
全部代碼
package main
import (
"fmt"
"sort"
)
type Monkey struct {
Name string
}
func (m *Monkey)climb(){
fmt.Println(m.Name,"會爬樹...")
}
//--------Flyable介面---------
type Flyable interface {
Fly()
}
//--------Swimmable介面-------
type Swimmable interface {
Swim()
}
//----------介面繼承--------------
type Skills interface {
Flyable
Swimmable
Change()
}
//-----------空介面-----------
type Null interface {
}
//---------不破壞結構體,添加屬性--------
type WuKong struct {
Monkey
Tool string
}
//---------不破壞繼承,擴展行為/方法--------
func (w *WuKong) Fly() {
fmt.Println("筋斗云,來...")
}
func (w *WuKong) Swim() {
fmt.Println("老龍王,俺老孫的金箍棒呢?")
}
func (w *WuKong) Change() {
fmt.Println("看我72變...")
}
type MonkeySlice []Monkey
//--------實作Len--------
func (m MonkeySlice) Len() int{
return len(m)
}
//---------實作Less---------
func (m MonkeySlice) Less(i,j int) bool {
return m[i].Name < m[j].Name
}
//----------實作Swap---------
func (m MonkeySlice) Swap(i,j int){
m[i],m[j] = m[j],m[i]
}
func main() {
//-----------介面體-------
w := WuKong{}
w.Name = "孫悟空"
//-----------使用方法------
w.climb()
//-----------使用實作的介面的方法---------
w.Fly()
//-----------結構體賦值給介面------------
var s Skills
s = &w
s.Change()
//----------空介面-------------
var null Null
null = w
wukong := null.(WuKong)
wukong.Swim()
//-----------結構體切片排序--------------
monkeys := MonkeySlice{{"峨眉猴"},{"齊天大圣"},{"金絲猴"},{"六耳獼猴"},{"孫悟空"}}
sort.Sort(monkeys)
fmt.Println(monkeys)
}
截圖

參考
Go標準庫-sort
更多Go相關內容:Go-Golang學習總結筆記
有問題請下方評論,轉載請注明出處,并附有原文鏈接,謝謝!如有侵權,請及時聯系,如果您感覺有所識訓,自愿打賞,可選擇支付寶18833895206(小于),您的支持是我不斷更新的動力,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/282359.html
標籤:區塊鏈
上一篇:【環境篇】Docker 匯出加載鏡像提示 docker: Error response from daemon: OCI runtime
下一篇:npm 安裝依賴報錯npm ERR! ERESOLVE unable to resolve dependency tree
