Go語言學習筆記---介面

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。下面定義了具有一個欄位和兩個方法的結構類型S代碼6.1type S struct { i int }func (p *S) Get() int { return p.i }func (p *S) Put(v int) { p.i = v }
也可以定義介面類型,僅僅是方法的集合。這裡定義了一個有兩個方法的介面I:type I interface {    Get() int    Put(int)}對於介面I,S是合法的實現,因為它定義了I所需的兩個方法。注意,即便是沒有明確定義S實現了I,這也是正確的。
介面值:例:func f(p I) {                //定義一個函數接受一個介面類型作為參數    fmt.Println(p.Get())     //p實現了介面I,必須有Get()方法    p.Put(1)                 //Put()方法是類似的}
這裡的變數p儲存了介面類型的值。因為S實現了I,可以調用f向其傳遞S類型的值的指標:var s S; f(&s)擷取s的地址,而不是S的值的原因,是因為在s的指標上定義了方法,參閱上面的代碼6.1。這並不是必須的——可以定義讓方法接受值——但是這樣的話Put方法就不會像期望的那樣工作了。實際上,無須明確一個類型是否實現了一個介面意味著Go實現了叫做duck typing的模式。這不是純粹的duck typing,因為如果可能的話Go編譯器將對類型是否實現了介面進行實現靜態檢查。假設需要在函數f中知道實際的類型。在Go中可以使用type switch得到。func f(p I) {
switch t := p.(type) {    //類型判斷。在switch語句中使用(type)。檔案類型到變數t;
case *S:             //p的實際類型是S的指標;
case *R:             //p的實際類型是R的指標;
case S:              //p的實際類型是S;
case R:              //p的實際類型是R;
default:             //實現了I的其他類型。
}
}
注意: element.(type)文法不能在switch外的任何邏輯裡面使用,如果你要在switch外面判斷一個類型就使用 comma-ok。
類型判斷不是唯一的運行時得到類型的方法。為了在運行時得到類型,同樣可以使用“comma, ok”來判斷一個介面類型是否實現了某個特定介面:if t, ok := something.(I); ok {// 對於某些實現了介面I 的// t 是其所擁有的類型}

Comma-ok斷言

Go語言裡面有一個文法,可以直接判斷是否是該類型的變數: value, ok = element.(T),這裡value就是變數的值,ok是一個bool類型,element是interface變數,T是斷言的類型。

如果element裡面確實儲存了T類型的數值,那麼ok返回true,否則返回false。

例:package main
import (    "fmt"    "strconv")
type Element interface{}type List [] Element
type Person struct {    name string    age int}
//定義了String方法,實現了fmt.Stringerfunc (p Person) String() string {    return "(name: " + p.name + " - age: "+strconv.Itoa(p.age)+ " years)"}
func main() {    list := make(List, 3)    list[0] = 1 // an int    list[1] = "Hello" // a string    list[2] = Person{"Dennis", 70}
    for index, element := range list {        if value, ok := element.(int); ok {            fmt.Printf("list[%d] is an int and its value is %d\n", index, value)        } else if value, ok := element.(string); ok {            fmt.Printf("list[%d] is a string and its value is %s\n", index, value)        } else if value, ok := element.(Person); ok {            fmt.Printf("list[%d] is a Person and its value is %s\n", index, value)        } else {            fmt.Println("list[%d] is of a different type", index)        }    }}輸出結果:list[0] is an int and its value is 1list[1] is a string and its value is Hellolist[2] is a Person and its value is (name: Dennis - age: 70 years)

確定一個變數實現了某個介面,可以使用:t := something.(I)
空介面由於每個類型都能匹配到空介面:interface{}。我們可以建立一個接受空介面作為參數的普通函數:Listing 6.2.用空介面作為參數的函數func g(something interface{}) int {    return something.(I).Get()}在這個函數中的return something.(I).Get()是有一點竅門的。值something具有類型interface{},這意味著方法沒有任何約束:它能包含任何類型。.(I)是類型斷言,用於轉換something到I類型的介面。如果有這個類型,則可以調用Get()函數。因此,如果建立一個*S類型的新變數,也可以調用g(),因為*S同樣實現了空介面。s = new(S)fmt.Println(g(s));例:package mainimport (    "fmt")func main(){    s  := new(S)    ss := "Hello world"    fmt.Printf("%d\n",g(s))    fmt.Printf("%s\n",demo(ss))}func g(something interface{}) int {    return something.(I).Get()                //?為什麼不是something.(S).Get()}func demo(something interface{}) string {    return something.(string)}type I interface {    Get() int    Put(int)}type S struct { i int }func (p *S) Get() int {    return p.i}func (p *S) Put(v int) {    p.i = v}
輸出結果:0Hello world
例2:package mainimport (    "fmt")func main(){    s  := S{1}    fmt.Printf("%d\n",g(s))}func g(something S) int {    return something.Get()}type S struct { i int }func (p *S) Get() int {    return p.i}func (p *S) Put(v int) {    p.i = v}
輸出結果:1
介面名字根據規則,單方法介面命名為方法名加上-er尾碼:Reader,Writer,Formatter等。有一堆這樣的命名,高效的反映了它們職責和包含的函數名。Read,Write,Close,Flush,String等等有著規範的聲明和含義。為了避免混淆,除非有類似的聲明和含義,否則不要讓方法與這些重名。相反的,如果類型實現了與眾所周知的類型相同的方法,那麼就用相同的名字和聲明;將字串轉換方法命名為String而不是ToString。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.