Go 方法、介面

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

在 Go 中,類型可以定義接收此類型的函數,即方法。每個類型都有介面,意味著對那個類型定義了方法集合。

下面定義了結構體類型 S 以及它的兩個方法:

type S struct { i int }func (p *S) Get() int { return p.i }func (p *S) Put(v int) { p.i = v }

方法

方法就是有接收者的函數。

可以在除了非本地類型(包括內建類型,比如 int)的任意類型上定義方法。然而可以為內建類型定義別名,然後就可以為別名定義方法。如

type Foo int // 為 int 定義別名 Foofunc (self Foo) Emit() {    fmt.Printf("%v", self)}

介面

介面定義為一個方法的集合。方法包含實際的代碼。換句話說,一個介面就是定義,而方法就是實現。因此,接收者不能定義為介面類型,這樣做的話會引起 invalid receiver type … 的編譯器錯誤。

來自語言說明書的權威內容:

接收者類型必須是T 或*T,這裡的 T 是類型名。 T 叫做接收者基礎類型或簡稱基礎類型。基礎類型一定不能是指標或介面類型,並且定義在與方法相同的包中。

// 定義了有兩個方法的介面 I,結構 S 實現了此介面type I interface {    Get() int    Put( int)}

可以定義介面類型的變數(介面值)作為函數的參數,實現了此介面的類型的變數可以作為實參傳遞給該介面變數並調用其方法。

func f(p I) {    fmt.Println(p.Get())    p.Put(1)}var s Sf(&s) // S 類型的變數 s 作為實參傳給介面。取地址是因為在 s 的指標上定義了方法,這樣可以修改 s;      // 如果在 s 上定義方法,則修改的只是 s 的副本

在 Go 中建立指向介面的指標是無意義的。建立介面值的指標也是非法的。

介面類型判斷

在 Go 中,要判斷傳遞給介面值的變數類型,可以在使用 type switch 得到。(type)只能在 switch 中使用。

// 另一個實現了 I 介面的 R 類型type R struct { i int }func (p *R) Get() int { return p.i }func (p *R) Put(v int) { p.i = v }func f(p I) {    switch t := p.(type) { // 判斷傳遞給 p 的實際類型        case *S: // 指向 S 的指標類型        case *R: // 指向 R 的指標類型        case S:  // S 類型        case R:  // R 類型        default: //實現了 I 介面的其他類型    }}

若要在 switch 外判斷一個介面類型是否實現了某個介面,可以使用“逗號 ok ”。

value, ok := Interfacevariable.(implementType)

其中 Interfacevariable 是介面變數(介面值),implementType 為實現此介面的類型,value 返回介面變數實際類型變數的值,如果該類型實現了此介面返回 true

type I interface{ // 有一個方法的介面 I    Get() Int}type Int int // Int 類型實現了 I 介面func (i Int) Get() Int{    return i}var myint Int = 5var inter I = myint // 變數賦值給介面val, ok := inter.(Int)fmt.Printf("%v, %v", val, ok) // 輸出為:5,true

空介面

每種類型都能匹配到空介面:interface{}。空介面類型對方法沒有任何約束(因為沒有方法),它能包含任意類型,也可以實現到其他介面類型的轉換。如果傳遞給該介面的類型變數實現了轉換後的介面則可以正常運行,否則出現執行階段錯誤。

func g(si interface{}) int {    return si.(I).Get()}s = new(S)g(s) // (I) 將 si 轉換到 I 類型的介面,s 實現了 Get 方法,因此可以調用 g()i := 5g(i) // 運行時出錯,因為 int 型沒有 Get 方法

還可以在介面中列出另一個介面,如

type Interface interface {    sort.Interface // 另一個介面    Push(x interface{})    Pop() interface{}}

自省和反射

著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.