Golang的接口

當一隻鳥走路像鴨子,游泳像鴨子,叫起來也像鴨子,那麼咱們就認爲它就是鴨子。this

Duck typing 的理念所以比喻得名。spa

Golang 經過 interface 實現 duck typing。 Effective Go 文章中這樣描述 interface: interfacecode

指定了一種描述對象行爲的方法:若是某樣東西能夠作這件事,這樣東西就能夠用在這裏。對象

再具體講, 就是當某個變量的類型實現了某個接口的全部方法 (這個時候能夠稱該類型實現blog

知足該接口) ,那麼這個變量就能用在要求這個接口的地方。接口

 

package main

import (
    "reflect"
    "fmt"
)

type Test struct {
}

func (this *Test)test() {
    fmt.Println("in test()")
}

type Tester interface {
    test()
}

func MakeTest1(v Tester) {
    fmt.Printf("\nIn Maketest1\n")
    v.(Tester).test()
}

func MakeTest2(v interface{}) {
    fmt.Printf("\nIn Maketest2\n")
    v.(Tester).test()
}

func main() {
    t := new(Test)
    var ti Tester
    ti = t
    ti.test()

    // 接口類型斷言
    // value爲Test類型的對象
    // 是ti的值
    value := ti.(Tester)
    fmt.Printf("\n方式1:\n")
    fmt.Println(reflect.TypeOf(value))
    value.test()

    // v是ti的值,是Test類型
    // Tester是接口類型
    if v, ok := ti.(Tester); ok {
        fmt.Printf("\n方式2:\n")
        fmt.Println(reflect.TypeOf(v))
        v.test()
    }

    // switch type專用組合
    // 若是須要在if中判斷能夠用上面的形式
    switch t := ti.(type) {
    case Tester:
        fmt.Printf("\n方式3:\n")
        fmt.Println("Tester")
        fmt.Println(reflect.TypeOf(t))
        t.test()
    default:
        fmt.Println("Unknow")
    }

    // 傳遞Test結構變量
    // 由於Test實現了Tester接口 
    MakeTest1(t)

    // 傳遞Tester接口變量
    MakeTest1(ti)

    // 傳遞Test結構變量
    // 由於Test實現了interface{}接口
    MakeTest2(t)

    // 傳遞Tester接口變量
    // 由於任何類型都實現了interface{}
    MakeTest2(ti)

}

 

 運行結果:ip

in test()

方式1:
*main.Test
in test()

方式2:
*main.Test
in test()

方式3:
Tester
*main.Test
in test()

In Maketest1
in test()

In Maketest1
in test()

In Maketest2
in test()

In Maketest2
in test()

Golang 裏面有個空的接口 interface{}, 大括號裏看上去什麼也沒有, 但認爲它有一個空get

的方法;Golang 裏的每一種類型或者你自定義的類型,無論有沒有添加了什麼具體的方法,it

都認爲有一個空的方法。所以每種類型自動實現了 interface{}接口,要求 interface{}的地方class

就能夠用任意類型的變量。

下載interface.go

相關文章
相關標籤/搜索