【Golang】Go语言类型断言

接口概念

一个接口的值(简称接口值)是由一个具体类型具体类型的值两部分组成的。这两部分分别称为接口的动态类型动态值

非空接口的底层数据结构是iface,其代码如下(代码位于src/runtime/runtime2.go中):

type iface struct{
    tab *itab			 	//itab存放类型及方法指针信息
    data unsafe.Pointer 	//数据信息
}

iface的结构很简单,有两个指针类型字段。

  • itab:用来存放接口自身类型和绑定的实例类型及实例相关的函数指针。
  • 数据指针data:指向接口绑定的实例的副本,接口的初始化也是一种值拷贝。

空接口的底层数据结构也很简单,代码如下:

type eface struct{
    _type *_type
    data unsafe.Pointer
}

从eface的数据结构可以看出,空接口不是真的为空,其保留了具体实例的类型和值拷贝,即便存放的具体类型是空的,空接口也不是空的。

可以使用类型断言来判断接口中的值,其语法格式:

x.(T)
// x表示为 interface{}的变量
// T表示断言x可能的类型 

该语法返回两个参数,第一个参数是x转化为T类型后的变量,第二个值是一个布尔值,若为true则表示断言成功,为false则表示断言失败。

x.(T)示例:

func main() {
	var x interface{}
	x = 666
	value,ok := x.(int)
	if ok == true{
		fmt.Println("断言成功,值为:",value)
	}else{
		fmt.Println("断言失败,x不是int类型")
	}
}

// 运行结果: 
// 断言成功,值为:666

x.(type) 这种方式的类型断言,就只能和 switch 搭配使用,因为它需要和多种类型比较判断,以确定其具体类型。

x.(type)示例:

func checkType(x interface{}){
	switch t := x.(type) {
	case string:
		fmt.Println("string类型: ",t)
	case int:
		fmt.Println("int类型: ",t)
	case bool:
		fmt.Println("bool类型: ",t)
        default:
        fmt.Println("未知类型")
	}
}

func main() {
	var x interface{}
	x = 666
	checkType(x)
	x = "test"
	checkType(x)
}

//运行结果:
//	int类型:  666
//	string类型:  test

注意

x.(type), x.(T) 中的 x 都必须是接口类型,否则会编译失败。

例如:

func main() {
	var x int //x为int类型
	x = 666
	v,ok := x.(int)//编译失败,提示invalid type assertion: x.(int) (non-interface type int on left)
	if ok == true{
		fmt.Println("int ",v)
	}else{
		fmt.Println("unknow")
	}
}

但此时x作为checkType函数参数时,编译通过。

因为x interface{}这个实例承载了x int类型的值。

func checkType(x interface{}){
	switch t := x.(type) {
	case string:
		fmt.Println("string类型: ",t)
	case int:
		fmt.Println("int类型: ",t)
	case bool:
		fmt.Println("bool类型: ",t)
	default:
		fmt.Println("未知类型")
	}
}

func main() {
	var x int //x为int类型
	x = 666
	checkType(x)
}

//运行结果:
//	int类型:  666
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值