當前位置:
首頁 > 最新 > 深入理解Go的interface

深入理解Go的interface

0. 引言

在 Golang 中,interface 是一個非常重要的概念和特性,之前寫過兩篇相關的文章:Golang 「泛型編程」,談一談 Golang 的 interface 和 reflect。然後在 Gopher China 2017 的會上又有一個關於 interface 的 topic: understanding golang interface(Gopher China) — youtube,作者是 Francesc。故在此做一個整理和補充。

1. What is Interface?

引用

In object-oriented programming, a protocol or interface is a common means for unrelated objects) to communicate with each other. These are definitions of methods) and values which the objects agree upon in order to co-operate. — wikipedia

這是 wikipedia 關於 protocal 的定義,將 interface 類比如 protocal 是一種非常助於理解的方式。protocol,中文一般叫做協議,比如網路傳輸中的 TCP 協議。protocol 可以認為是一種雙方為了交流而做出的約定,interface 可以類比如此。

在 Golang 中,interface 是一種抽象類型,相對於抽象類型的是具體類型(concrete type):int,string。如下是 io 包裡面的例子。

// Writer is the interface that wraps the basic Write method. // // Write writes len(p) bytes from p to the underlying data stream. // It returns the number of bytes written from p (0 >= 1 { maxDepth++ } maxDepth *= 2 quickSort(data, 0, n, maxDepth) }

Sort 函數的形參是一個 interface,包含了三個方法:Len(),Less(i,j int),Swap(i, j int)。使用的時候不管數組的元素類型是什麼類型(int, float, string…),只要我們實現了這三個方法就可以使用 Sort 函數,這樣就實現了「泛型編程」。有一點比較麻煩的是,我們需要將數組自定義一下。下面是一個例子。

type Person struct { Name stringAge int } func (p Person) String() string { return fmt.Sprintf("%s: %d", p.Name, p.Age) } // ByAge implements sort.Interface for []Person based on // the Age field. type ByAge []Person //自定義 func (a ByAge) Len() int { return len(a) } func (a ByAge) Swap(i, j int) { a[i], a[j] = a[j], a[i] } func (a ByAge) Less(i, j int) bool { return a[i].Age

另外 Fransesc 在 Gopher China 上還提到了一個比較有趣的東西和大家分享一下。在我們設計函數的時候,下面是一個比較好的準則。

Be conservative in what you send, be liberal in what you accept. — Robustness Principle

對應到 Golang 就是:

Return concrete types, receive interfaces as parameter. — Robustness Principle applied to Go

話說這麼說,但是當我們翻閱 Golang 源碼的時候,有些函數的返回值也是 interface。

2.2 hiding implement detail

隱藏具體實現,這個很好理解。比如我設計一個函數給你返回一個 interface,那麼你只能通過 interface 裡面的方法來做一些操作,但是內部的具體實現是完全不知道的。Francesc 舉了個 context 的例子。 context 最先由 google 提供,現在已經納入了標準庫,而且在原有 context 的基礎上增加了:cancelCtx,timerCtx,valueCtx。語言的表達有時候略顯蒼白無力,看一下 context 包的代碼吧。

func WithCancel(parent Context) (ctx Context, cancel CancelFunc) { c := newCancelCtx(parent) propagateCancel(parent, &c) return &c, func() { c.cancel(true, Canceled) } }

表明上 WithCancel 函數返回的還是一個 Context interface,但是這個 interface 的具體實現是 cancelCtx struct。

// newCancelCtx returns an initialized cancelCtx. func newCancelCtx(parent Context) cancelCtx { return cancelCtx{ Context: parent, done: make(chan struct{}), } } // A cancelCtx can be canceled. When canceled, it also cancels any children // that implement canceler. type cancelCtx struct { Context done chan struct{} // closed by the first cancel call. mu sync.Mutex children map[canceler]struct{} // set to nil by the first cancel call err error // set to non-nil by the first cancel call}func (c *cancelCtx) Done()

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 推酷 的精彩文章:

懶人設計師必須知道的外部免費資源網站
分時租賃企業「Ponycar」宣布獲1.5億B輪融資,投資方為惠友和OPPO
二叉樹的那些使用
Docker用以提高Linux內核安全性的三大熱點技術
在迷茫中堅守的Neri,可能是惠普企業的最後一位高管

TAG:推酷 |

您可能感興趣

MapReduce Shuffle深入理解
從One-hot,Word embedding到Transformer,一步步教你理解Bert
徹底理解cookie、session、token
Windows PowerShell進階 理解Module
理解 Linux 中的 /etc/services 文件
我所理解的#ShotoniPhone
理解foreach, for in, for of 之間的異同
Glibc堆漏洞利用基礎-深入理解ptmalloc2 part1
快速理解Token,Cookie,Session
深入理解 Web Server 原理與實踐:Nginx
深入理解 ES Modules
Cookie,Session和Token概念的正確理解
理解 OutOfMemoryError 異常
「straight from the horse s mouth」不是「從馬的嘴」,這樣理解就錯了
理解 Python 的 for 循環
阿里CEO張勇:我們理解AI是Alibaba Intelligence
簡單理解Vue中的nextTick
我所理解的 Smartisan OS
徹底理解 Node.js 中的回調(Callback)函數
通過 Q-learning 深入理解強化學習