Go语言--接口的类型断言

 定义

类型断言是判断接口的数据类型,语法如下

x.(T)

x:表示类型为interface{}的变量

T:表示断言可能的数据类型

类型断言有两个返回值,第一个返回值是空接口的数值和数据类型;第二个返回值是布尔型,判断x是不是T的数据类型。

 具体实现

类型断言有那么一点像C++的函数模板,就像我们对接口参数化,等到运行时根据实际情况再对它赋值。通过类型断言我们得到接口的数据类型后,再对其进行相关操作。我们直接来看例子,完整代码如下

package main

import "fmt"

type sinner struct {
	name   string
	loc    string
	rating float64
	id     int
}
type initialize interface {
	init(sinner) sinner
}

func getData(s interface{}) {
	if data, flag := s.(sinner); flag {
		fmt.Printf("name is %v\n", data.name)
	} else if data, flag := s.(float64); flag {
		fmt.Printf("float64 is %v\n", data)
	} else if data, flag := s.(string); flag {
		fmt.Printf("string is %v\n", data)
	}
}
func (*sinner) init(s sinner) sinner {
	s = sinner{name: "Ishmael", loc: "Limbus Company", rating: 9.9, id: 1}
	return s
}
func startInit(i initialize, s sinner) {

	tmp := i.init(s)
	getData(tmp)
	getData(tmp.rating)
	getData(tmp.loc)
}
func main() {
	var ishmael sinner
	startInit(&ishmael, ishmael)
}

我们定义了一个结构体sinner和一个接口initialize,并通过结构体去绑定接口来实现接口的里的init方法,这一块知识主要是这篇文章的知识Go语言--接口的定义与使用

通过接口我们为结构体内不同类型的变量赋初始值。我们删去这些代码,只保留类型断言的部分再看看。

type sinner struct {
	name   string //"Ishmael"
	loc    string //"Limbus Company"
	rating float64 //9.9
	id     int //1
}

func getData(s interface{}) {
	if data, flag := s.(sinner); flag {
		fmt.Printf("name is %v\n", data.name)
	} else if data, flag := s.(float64); flag {
		fmt.Printf("float64 is %v\n", data)
	} else if data, flag := s.(string); flag {
		fmt.Printf("string is %v\n", data)
	}
}
func (*sinner) init(s sinner) sinner {
	s = sinner{name: "Ishmael", loc: "Limbus Company", rating: 9.9, id: 1}
	return s
}
func startInit(i initialize, s sinner) {

	tmp := i.init(s) //type:sinner
	getData(tmp)
	getData(tmp.rating)
	getData(tmp.loc)
}

可以看到,我们定义的getData()方法,传入的参数类型为interface。但在startInit()方法中,我们调用getData()时传入的是三种不同类型的参数:结构体类型,flaot64双精度浮点数类型,string类型。就是没有interface类型。

尽管如此,程序还是能正常运行,结果如下

name is Ishmael
float64 is 9.9          
string is Limbus Company

这是由于:空接口是接口类型的特殊形式,空接口没有设置任何方法,任何变量都可以使用空接口。空接口可以保存任意数据,也可以从空接口中取出数据。

所以我们传入的结构体类型,flaot64双精度浮点数类型,string类型,都被interface保存了下列。(不能说被转换为了interface类型,接口只是保存了我们存进去的数据类型,我们取出来的不是接口而是那个数据)

在if判断语句中,可以看到当s的类型为sinner结构体类型/float64/string类型时,才会执行对应的语句。

if data, flag := s.(sinner); flag {
        fmt.Printf("name is %v\n", data.name)
    } 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值