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{}的地方
就可以用任意类型的变量。