funcmain() {var x Sayer// 声明一个Sayer类型的变量x a :=cat{} // 实例化一个cat b :=dog{} // 实例化一个dog x = a // 可以把cat实例直接赋值给x x.say() // 喵喵喵 x = b // 可以把dog实例直接赋值给x x.say() // 汪汪汪}
值接收者和指针接收者实现接口的区别
使用值接收者实现接口和使用指针接收者实现接口有什么区别呢?接下来我们通过一个例子看一下其中的区别。
我们有一个Mover接口和一个dog结构体。
typeMoverinterface {move()}typedogstruct {}
值接收者实现接口
func (d dog) move() { fmt.Println("狗会动")}
此时实现接口的是dog类型:
funcmain() {var x Movervar wangcai =dog{} // 旺财是dog类型 x = wangcai // x可以接收dog类型var fugui =&dog{} // 富贵是*dog类型 x = fugui // x可以接收*dog类型 x.move()}
typedogstruct { name string}// 实现Sayer接口func (d dog) say() { fmt.Printf("%s会叫汪汪汪\n", d.name)}// 实现Mover接口func (d dog) move() { fmt.Printf("%s会动\n", d.name)}funcmain() {var x Sayervar y Movervar a =dog{name: "旺财"} x = a y = a x.say() y.move()}
typecatstruct { name string}func (c cat) say() { fmt.Println("喵喵喵")}func (c cat) move() { fmt.Println("猫会动")}funcmain() {var x animal x =cat{name: "花花"} x.move() x.say()}
空接口
空接口的定义
空接口是指没有定义任何方法的接口。因此任何类型都实现了空接口。
空接口类型的变量可以存储任意类型的变量。
funcmain() {// 定义一个空接口xvar x interface{} s :="Hello yokaimeow" x = s fmt.Printf("type:%T value:%v\n", x, x) i :=100 x = i fmt.Printf("type:%T value:%v\n", x, x) b :=true x = b fmt.Printf("type:%T value:%v\n", x, x)}
空接口的应用
空接口作为函数的参数
使用空接口实现可以接收任意类型的函数参数。
// 空接口作为函数参数funcshow(a interface{}) { fmt.Printf("type:%T value:%v\n", a, a)}
funcmain() {var x interface{} x ="Hello yokaimeow" v, ok := x.(string)if ok { fmt.Println(v) } else { fmt.Println("类型断言失败") }}
上面的示例中如果要断言多次就需要写多个if判断,这个时候我们可以使用switch语句来实现:
funcjustifyType(x interface{}) {switch v := x.(type) {casestring: fmt.Printf("x is a string,value is %v\n", v)caseint: fmt.Printf("x is a int is %v\n", v)casebool: fmt.Printf("x is a bool is %v\n", v)default: fmt.Println("unsupport type!") }}