在上面的代码中,一个接口实例化出了两个变量 i, j i 使用 vertex 结构实现了 fun()方法 j 使用 MyFloat 结构实现了 fun()方法 就因为他们在实现的时候,选择的实现方式不同,他们的 fun() 方法也就不一样 运行结果:
1 2 3 4
用vertex实现了方法 {hehe} 用MyFloat实现了方法 20
空接口
指定了零个方法的接口值被称为空接口
1
interface{}
空接口可保存任何类型的值,因为每个类型都至少实现了零个方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14
funcmain() { var i interface{} describe(i)
i = 42 describe(i)
i = "hello" describe(i) }
funcdescribe(i interface{}) { fmt.Printf("(%v, %T)\n", i, i) }
空接口有一个好处就是谁都可以用,连空值也可以 空接口还可以和类型断言一起使用,可以用来做类型选择
类型断言
用来判断一个值的类型的接口 用法如下:
1
t, ok := i.(T)
如果 i 确实是 T 类型的值,那么 t 就会获取到 i 的值 true 如果 i 不是 T 类型的值, 那么 t 会获取到 0, ok 获取到 false 第二个值 ok 是可以不写的,只是在类型判断错误的时候程序会报错
1 2 3 4 5 6 7 8 9 10 11 12 13
var i interface{} = "hello"
s := i.(string) fmt.Println(s)
s, ok := i.(string) fmt.Println(s, ok)
f, ok := i.(float64) fmt.Println(f, ok)
f = i.(float64) // 报错 fmt.Println(f)
类型选择
类型选择和类型断言很像,只是把 i.(T) 中的 T 换成了关键字 type
1 2 3 4 5 6 7 8
switch v := i.(type) { caseint: fmt.Printf("Type is int value is %v\n", v) casestring: fmt.Printf("Type is string value is %v\n", v) default: fmt.Printf("I don't know type %T!\n", v) }