接口类型
go语言中接口(interface)是一种类型,一种抽象的类型。
interface是一组method的集合,是duck-type programming的一种体现。接口做的事情就像是定义一个协议(规则),只要一台机器有洗衣服和甩干的功能,我就称它为洗衣机。不关心属性(数据),只关心行为(方法)。
空接口
空接口的定义
interface{} 类型,空接口。interface{} 类型是没有方法的接口。由于没有 implements 关键字,所以所有类型都至少实现了 0 个方法,所以 所有类型都实现了空接口。这意味着,如果编写一个函数以 interface{} 值作为参数,那么可以为该函数提供任何值。
func main() {// 定义一个空接口xvar x interface{}s := "Hello11"x = sfmt.Printf("type:%T value:%v\n", x, x)i := 100x = ifmt.Printf("type:%T value:%v\n", x, x)b := truex = bfmt.Printf("type:%T value:%v\n", x, x)}
空接口作为map的值
package mainimport "fmt"//空接口type null1 interface {}//空接口可做任意类型 做map值 任意数值func main() {map1 := make(map[string]interface{},100)map1["z"] = 100map1["d"] = "ll"map1["ture"] = truefmt.Println(map1)}
类型断言
空接口可以存储任意类型的值,那我们如何获取其存储的具体数据呢?
想要判断空接口中的值这个时候就可以使用类型断言,其语法格式:
x.(T)
其中:
- x:表示类型为interface{}的变量
- T:表示断言x可能是的类型。
该语法返回两个参数,第一个参数是x转化为T类型后的变量,第二个值是一个布尔值,若为true则表示断言成功,为false则表示断言失败。
func main() {var a interface{}a = "1111"v, ok := a.(string)if ok {fmt.Println(a)} else {fmt.Println("failed")}}
值接收者和指针接收者实现接口的区别
//定义动物接口类型type animal interface {speak()move()}type cat struct {name string}//值接受者---------------------/*func (c cat) speak() {fmt.Println("miao")}func (c cat) move() {fmt.Println("move11")}func main() {var a animalvar b animalling1 := cat{"lingling"}tom := &cat{"xiaohua"} //语法糖 xiangdangyu *tom := &cata = tomb = ling1tom.speak() // (*tom.speak())fmt.Println(a)}
使用值接收者实现接口之后,不管是cat结构体还是结构体指针cat类型的变量都可以赋值给该接口变量。因为Go语言中有对指针类型变量求值的语法糖,cat指针内部会自动求值tom。
//指针接受者---------------------func (c *cat) speak() {fmt.Println("miao")}func (c *cat) move() {fmt.Println("move11")}func main() {var a animaltom := &cat{"xiaohua"} //语法糖 xiangdangyu *tom := &cata = tomtom.speak() // (*tom.speak())a.move()}
此时实现接口的是cat类型,所以不能给a传入cat类型的tom,此时a只能存储cat类型的值。
