栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Go语言

Golang type assertion 类型断言

Go语言 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Golang type assertion 类型断言

前言

在很多情况下,接口类型没有办法直接作为值来使用,或者说我们需要检查某个接口变量是否为我们期望的类型,就需要先使用类型断言 (type assertion)进行类型判断以及转换。

基本用法 断言语句

一个类型断言语句检查它操作对象的动态类型是否和断言的类型匹配。

value, ok := x.(T)

各变量含义为:
x :要判断的变量,必须为接口类型
T :被判断的目标类型
value :成功转换后的值,动态类型
ok:是否为目标类型,bool 类型

需要注意的是,如果 x == nil,那么断言一定失败。

如果在已经确定 x 就是 T 类型的前提下,也可以省略 ok,但是只要类型不匹配,就会报 panic

value := x.(T)
断言类型种类

类型断言语句中,T 可以是具体类型也可以是接口类型。

具体类型

如果 T 是一个具体类型,那么类型断言会检查 x 的动态类型是否和 T 相同,如果相同,ok = true,value 为转换后的值,如果不相同,ok = false 且 value = nil,但是需要注意 x 必须为接口类型,否则编译会失败,使用示例如下:

// 错误用法
// combile error: invalid type assertion: num.(int) (non-interface type int on left)
num := 10
if v, ok := num.(int); ok {
	fmt.Println(v)
}

// 正确用法
if v, ok := interface{}(num).(int); ok {
	fmt.Println(v) // out: 10
}
接口类型

如果 T 是一个接口类型,那么类型断言会检查 x的动态类型是否满足 T,即检查 x 是否实现了 T 接口。如果这个检查成功了,x 的动态值不会被提取,返回值是一个类型为 T 的接口值。换句话说,对一个接口类型的类型断言改变了类型的表述方式,改变了可以获取的方法集合(通常可以使用更多的方法),但是它保护了接口值内部的动态类型和值。

var w io.Writer  // w 只能调用 Write 方法
w = os.Stdout
rw := w.(io.ReadWriter) // success: *os.File has both Read and Write
// rw 可以使用 Read 和 Write 方法

如果 x 不满足 T,就会 panic

type HelloInterface interface {
	Hello()
}

var w io.Writer = os.Stdout
hello := w.(HelloInterface) // panic: interface conversion: *os.File is not interfacetest.HelloInterface: missing method Hello

type switch

实际使用中,通常会将类型断言与 switch 结合来判断某个变量或者参数的类型,这时候 T 为 type,如官网给出的例子:

switch i := x.(type) {
case nil:
	printString("x is nil")                // type of i is type of x (interface{})
case int:
	printInt(i)                            // type of i is int
case float64:
	printFloat64(i)                        // type of i is float64
case func(int) float64:
	printFunction(i)                       // type of i is func(int) float64
case bool, string:
	printString("type is bool or string")  // type of i is type of x bool or string
default:
	printString("don't know the type")     // type of i is type of x (interface{})
}
基于断言识别错误类型

实际的开发过程中,通常会自定义一些扩展的错误类型来承载比原生 error 更复杂的信息,如:

type GError struct {
	Code    string `json:"code"`
	Message string `json:"message"`
}

func (g GError) Error() string {
	return fmt.Sprintf("Code:%s, Message:%s", g.Code, g.Message)
}

func (g GError) GetCode() string {
	return g.Code
}

func (g GError) GetMessage() string {
	return g.Message
}

GError 类型实现了 error 接口,那么当我们接收到一个错误,可以用类型断言来识别是否是 GError,并且做出对应的处理。

func callapi() *rest.GError {
}

err := callapi()
if err != nil {
	if gErr, ok := err.(*rest.GError); ok {
		fmt.Println(gErr.Error())
	} else {
		fmt.Println("system error")
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/993584.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号