华子的代码空间

逆水行舟,不进则退。 关注系统编程、网络编程、并发、分布式。

Golang的接口

当一只鸟走路像鸭子,游泳像鸭子,叫起来也像鸭子,那么我们就认为它就是鸭子。

Duck typing 的理念因此比喻得名。

Golang 通过 interface 实现 duck typing。 Effective Go 文章中这样描述 interface: interface

指定了一种描述对象行为的方法:如果某样东西可以做这件事,这样东西就可以用在这里。

再具体讲, 就是当某个变量的类型实现了某个接口的所有方法 (这个时候可以称该类型实现

满足该接口) ,那么这个变量就能用在要求这个接口的地方。

 

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)

}

 

 运行结果:

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{}, 大括号里看上去什么也没有, 但认为它有一个空

的方法;Golang 里的每一种类型或者你自定义的类型,不管有没有添加了什么具体的方法,

都认为有一个空的方法。因此每种类型自动实现了 interface{}接口,要求 interface{}的地方

就可以用任意类型的变量。

下载interface.go

posted on 2014-01-05 19:39  华子的代码空间  阅读(1060)  评论(0编辑  收藏  举报

导航