Go的类型断言解析

常常地咱们对一个接口值的动态类型是不肯定的,如方法的形参为接口类型时,此时就须要检验它是否符合咱们须要的类型。
类型断言是一个使用在接口值上的操做。
html

若是对Golang的接口和接口值的概念不熟悉,看这里:Go的接口总结
断言类型的语法:x.(T),这里x表示一个接口的类型,T表示一个类型(也可为接口类型)。
一个类型断言检查一个接口对象x的动态类型是否和断言的类型T匹配。
spa

类型断言分两种状况:
第一种若是断言的类型T是一个具体类型,类型断言x.(T)就检查x的动态类型是否和T的类型相同。
htm

  • 若是这个检查成功了,类型断言的结果是一个类型为T的对象,该对象的值为接口变量x的动态值。换句话说,具体类型的类型断言从它的操做对象中得到具体的值。
  • 若是检查失败,接下来这个操做会抛出panic,除非用两个变量来接收检查结果,如:f, ok := w.(*os.File)

第二种若是断言的类型T是一个接口类型,类型断言x.(T)检查x的动态类型是否知足T接口。
对象

  • 若是这个检查成功,则检查结果的接口值的动态类型和动态值不变,可是该接口值的类型被转换为接口类型T。换句话说,对一个接口类型的类型断言改变了类型的表述方式,改变了能够获取的方法集合(一般更大),可是它保护了接口值内部的动态类型和值的部分。
  • 若是检查失败,接下来这个操做会抛出panic,除非用两个变量来接收检查结果,如:f, ok := w.(io.ReadWriter)

注意:
blog

  • 若是断言的操做对象x是一个nil接口值,那么不论被断言的类型T是什么这个类型断言都会失败。
  • 咱们几乎不须要对一个更少限制性的接口类型(更少的方法集合)作断言,由于它表现的就像赋值操做同样,除了对于nil接口值的状况。

示例代码:接口

  

//===接口=====
type Tester interface {
	getName()string
}
type Tester2 interface {
	printName()
}
//===Person类型====
type Person struct {
	name string
}
func (p Person)getName() string {
	return p.name
}
func (p Person) printName() {
	fmt.Println(p.name)
}
//============
func main() {
	var t Tester
	t = Person{"xiaohua"}
	check(t)
}
func check(t Tester)  {
    //第一种状况
	if f, ok1 := t.(Person);ok1 {
		fmt.Printf("%T\n%s\n",f,f.getName())
	}
    //第二种状况
	if t, ok2 := t.(Tester2);ok2 {  //重用变量名t(无需从新声明)
		check2(t) //若类型断言为true,则新的t被转型为Tester2接口类型,但其动态类型和动态值不变
	}
}
func check2(t Tester2)  {
	t.printName()
}

 执行结果:get

main.Person
xiaohua
xiaohuastring

相关文章
相关标签/搜索