在阅读之前,建议先行阅读从学习assert的用法开始理解如何写“专业的程序”
断言
断言Type Assertion是编程术语,表示为布尔表达式
类型断言的必要条件时待判断类型必须是接口,否则无法断言:
var i int = 10
v := i.(int) // 错误
在[Introduction]接口/空接口中提到了空接口的使用方式,一个类型在通过in interface{}的方式传递进来的时候,自动转为interface{}空接口的类型,其原因是所有类型都实现了空接口。在参数传递的时候常常需要使用空接口,例如:
func funcA(in interface{}) string {
return string(in)
}
此时编译器将返回:
cannot convert a (type interface{}) to type string: need type assertion
因为此时没有进行类型断言,对于判断一个空接口储存到底为何种类型时有以下三种方法:
直接断言
如果断言的类型是一个具体类型如string,类型断言x.(T)就检查x的动态类型是否和T的类型相同:
var unknow interface{}
unknow = "unknowtype"
val, ok := unknow.(string) // return true , unknow is string ; unknow赋值给val
如果断言的类型T是一个接口类型,类型断言x.(T)检查x的动态类型是否满足T接口
反射
在上一篇...中,也可以使用反射来确定类型。反射需要import reflect使用包内方法判断类型:
retType = reflect.TypeOf(unknow)
val = reflect.ValueOf(unknow)
type关键字判断
和直接断言类似,使用swich-case语句来判断是否为某一类型
switch unknow.(type){
case string:
// string类型
case int:
// int类型
}
类型转换
对于空接口赋值的类不能直接调用其内部方法,需要进行类型转换后转换为相应的类后才可以调用内部的方法:
import (
"fmt"
)
type Name struct {
string
}
func (name Name) hello() {
fmt.Println(name.string)
}
func main() {
var name interface{} = new(Name)
//name.hello() 这是错误的
f := name.(Name)
f.hello()
}