Go语言interface万能类型及其类型断言(18)| Go主题月

2,214 阅读2分钟

Go语言接口也叫interface,interface里面主要是定义一些方法名称,前面第二篇讲过,这个高度抽象的类型不理解它很容易忘,而且有一些高级用法需要认真研究才能懂,通常用由结构体(sctuct)来声明方法并实现它们,今天再仔细讲讲它的高级用法

万能类型

Go语言的基础数据类型都实现了interface{},也就是说interface{}这个空接口都能以引用任意的数据类型,例如int,string,float,struct,怎么引用呢?那就是在函数的形参可以使用空接口,实参可以是任意的数据类型,我们来举一个例子:

package main
import "fmt"
func showAny(mytest interface{}){
	fmt.Println(mytest)   //直接打印输出传入的interface
}

func main() {
	type user struct{
		name string
	}
	showAny("string test")
	showAny(123)
	showAny(123.456)
	worker :=user{"土味挖掘机"}
	showAny(worker)
}

go run main.go看看运行结果: image.png 从运行结果可以看的出来,空接口的确可以引用任意的数据类型。这不就是面对对象三大特征特征:抽象、继承、多态中多态的概念吗?

psb.gif

类型断言

断言通俗来说就是判断变量的类型,在Gin框架的文档中也有类似的断言的过程:

image.png binding.Validator.Engine()是第三方包实现的接口,里面的*validator.Validate就是指针传递的验证内容。
现在就实现一个简单的类型断言吧,改一下上面的代码例子,改一下showAny函数的内容,判断接口引用的内容:

package main
import "fmt"

type user struct{
	name string
}
func showAny(mytest interface{}){
	_,ok:=mytest.(string)
	if ok{
		fmt.Printf("%s是:字符串\n",mytest)
	}
	_,ok=mytest.(int)
	if ok{
		fmt.Printf("%d是:整数\n",mytest)
	}
	_,ok=mytest.(float64)
	if ok{
		fmt.Printf("%g是:浮点数\n",mytest)
	}
	_,ok=mytest.(user)
	if ok{
		fmt.Printf("%s是:user结构体\n",mytest)
	}

}

func main() {
	showAny("string test")
	showAny(123)
	showAny(123.456)
	worker :=user{"土味挖掘机"}
	showAny(worker)
}

执行结果:

image.png 所以使用mytest.(type)来判断mytest接口的内容,如果返回的第二个参数不为False,那么就是断言成功,判断类型正确,为False就继续执行下面的判断。 image.png

总结

之前讲过interface 的普通的用法,可以用任何定义的类型实现任何接口,今天说了一下空接口可以引用任何类型,也可以做类型断言,体现了接口灵活强大,体现了Go语言多态的特征。

image.png