go語言學習-接口


Go語言中雖然沒有傳統面向對象語言中類、集成的概念,不過提供了接口的支持,可以使用接口來使用一些面向對象的特性。

在 go 語言中,的接口有下面幾個特點:

  • 可以包含0個或多個方法的簽名
  • 只定義方法的簽名,不包含實現
  • 實現接口不需要顯式的聲明,只需實現相應方法即可

接口的定義

定義方式如下:

type Namer interface {
    method1(param_list) return_list
    method2(param_list) return_list
    ...
}

這里的 Namer 就是接口的名字,只要符合標識符的規則即可。不過,通常約定的接口的名字最好以 er, r, able 結尾(視情況而定),這樣一眼就知道它是接口。

實現接口

在 go 中實現接口很簡單,不需要顯式的聲明實現了某個接口,想要實現某個接口,只需要實現接口中的所有方法即可。

package main

import "fmt"
import "math"

type Shaper interface {
    Area() float32
    Circumference() float32
}

type Rect struct {
    Width float32
    Height float32
}

type Circle struct {
    Radius float32
}

func (r Rect) Area() int {
    return r.Width * r.Height
}

func (r Rect) Circumference() int {
    return 2 * (r.Width + r.Height)
}

func (c Circle) Area() int {
    return math.Pi * c.Radius * c.Radius
}

func (c Circle) Circumference() int {
    return math.Pi * 2 * c.Radius
}

func main() {
    r := Rect{10, 20}
    fmt.Printf("Rect w: %f, d: %f, Area: %f, Circumference: %f", r.Width, r.Height, r.Area(), r.Circumference())

    c := Circle{5}
    fmt.Printf("Circle r: %f, Area: %f, Circumference: %f", c.Radius, c.Area(), c.Circumference())    
}

上面我們定義了一個 Shaper 的接口,其中包含兩個方法 Area 和 Circumference,分別用來計算面積和周長。然后我們定義了兩個結構體 Rect, Circle 並分別實現了這兩個方法。但是上面的程序似乎並沒有體現出接口和兩個實現類型的關系,下面我們將他們關聯起來使用:

func showInfo(s Shaper) {
    fmt.Printf("Area: %f, Circumference: %f", s.Area(), s.Circumference())
}

注意,這里方法的參數是一個接口類型的,因此我們可以將實現接口的類型的實例傳遞進去,像下面這樣:

r := Rect{10, 20}
showInfo(r)

c := Circle{5}
showInfo(c)

獲取實現接口的實際類型

在上面的 showInfo 中我們傳入了接口類型的對象,如果將實現了接口的類型傳遞進去,那么會將實際類型的其他特性掩蓋住,因此通常我們會想要獲取其真正的類型, 可以使用下面的方法:

func showInfo(s Shaper) {
    switch s.(type) {
    case Rect:
        fmt.Println("This is Rect")
    case Circle:
        fmt.Println("This is Circle")        
    }
    fmt.Printf("Area: %f, Circumference: %f\n", s.Area(), s.Circumference())
}

另外可以使用類型斷言,來判斷某一時刻接口是否是某個具體類型

v, ok := s.(Rect)   // s 是一個接口類型

如果 s 此時實際上是 Rect 類型,那么會將 s 轉換為 Rect 類型,並且 ok 為 true。否則 ok 為 false。

標准庫中的常用接口

io.Reader 和 io.Writer

這兩個接口定義了實現io功能的基本操作,因此某種類型只要實現了這兩個接口就可以進行io操作。

Reader 接口的定義為:

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

僅僅只有這一個方法,Read方法將從數據流中讀取 len(p) 個字節的數據到字節數組 p 中,並且返回讀取的字節數(即使發生了錯誤,n也會返回已經讀取的字節數)。

我們可能會經常用到的實現了 Reader 接口的對象有: os.Stdin(標准輸入), os.File的實例(文件對象)等等, 我們可以對其調用 Read 方法來讀取數據。

Writer 接口的定義:

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

Write 將 len(p) 個字節的數據從 p 中寫入到基本數據流中。寫入的字節數 n(0 <= n <= len(p))以及任何遇到的引起寫入提前停止的錯誤。

類似的實現了 Writer 接口的對象有: os.Stdout, os.Stderr, os.File 等等。可以使用 Write 方法向其中寫入數據。

標准庫中定義了很多的接口,這里只是簡單的提一下,更多內容還是要去查看標准庫的文檔。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM