Go 關於interface的理解(一)

Go 中的 interface 是一種抽象類型。一個 interface 就是包含了一系列行爲的method集合。 關於 interface 的定義,以 Writer 爲例:安全

package io
type Writer interface {
    Write(p []byte) (n int, err error)
}

Go 中的 interface 屬於隱式接口。一個類型若是擁有一個接口須要的全部方法,那麼這個類型就實現了這個接口。函數


在標準庫 fmt 包中的一系列方法能夠很好地詮釋 interface 是如何應用到實踐當中的。指針

package fmt

func Fprintf(w io.Writer, format string, args ...interface{}) (int, error)

func Printf(format string, args ...interface{}) (int, error) {
    return Fprintf(os.Stdout, format, args...)
}

func Sprintf(format string, args ...interface{}) string {
    var buf bytes.Buffer
    Fprintf(&buf, format, args...)
    return buf.String()
}

Fprintf 的前綴 F 表示文件(File)也代表格式化輸出結果應該被寫入第一個參數提供的文件中。
在Printf函數中的第一個參數os.Stdout是*os.File類型;
在sprintf函數中的第一個參數&buf是一個指針,指向能夠寫入字節的內存緩衝區;
而Fprintf函數中的第一個參數是一個 interface 類型 io.Writer。io.Writer 定義了函數 Fprintf 和這個函數調用者之間的約定,該約定保證了 Fprintf 接受任何知足 io.Writer 接口的值。
由於 fmt.Fprintf 函數沒有對具體操做的值作任何假設而是進京經過 io.Writer 接口的約定來保證行爲,因此第一個參數能夠安全地傳入任何一個具體類型的值,只須要它能知足 io.Writer 接口。
一個類型能夠自由的使用另外一個知足相同接口的類型來進行替換被稱做可替換性(LSP里氏替換)。這是一個面向對象的特徵。code


定義 interface
以標準庫中的 io 包爲例, io 包中定義了不少有用的 interface :orm

package io

type Reader interface {
    Read(p []byte) (n int, err error)
}

type Writer interface {
    Write(p []byte) (n int, err error)
}

type Closer interface {
    Close() error
}
/* Reader 表明任何能夠去讀 byte 的類型, Writer 表明任何能夠寫入 byte 的類型, Closer 表明任何能夠執行 close 的類型 */

除此以外,還能在 io 包中發現其餘組合式的 interface:對象

package io

type ReaderWriter interface {
    Reader
    Writer
}

type ReadWriteCloser interface {
    Reader
    Writer
    Closer
}
/*該語法和結構體內嵌類似,能夠用這種方式簡寫命名一個接口,稱爲接口內嵌*/

實現接口的條件
一個類型若是擁有一個接口須要的全部方法,那麼這個類型就實現了這個接口。
接口指定的規則也很是簡單:表達一個類型屬於某個接口只要這個類型實現這個接口,因此:接口

var w io.Writer
w = os.Stdout          //OK: *os.File has Write method
w = new(bytes.Buffer)  //OK: *bytes.Buffer has write method
w = time.Second        //compile error: time.Duration lacks Write method

var rwc io.ReadWriteCloser
rwc = os.Stdout        //OK: *os.File has Read, Write, Close methods
rwc = new(bytes.Buffer)//compile error: *bytes.Buffer lacks Close method

/* 這個規則甚至適用於等式右邊自己也是一個接口類型 */
w = rwc         // OK: io.ReadWriteCloser has Write method
rwc = w         // compile error: io.Writer lacks Close method
相關文章
相關標籤/搜索