类型断言:如何检测和转换接口变量的类型

本文介绍如何在Go语言中使用类型断言来检测接口变量中存储的实际类型,并通过一个示例程序展示了如何判断接口变量是否包含特定类型的值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简介

一个接口类型的变量 varI 中可以包含任何类型的值,必须有一种方式来检测它的 动态 类型,即运行时在变量中存储的值的实际类型。在执行过程中动态类型可能会有所不同,但是它总是可以分配给接口变量本身的类型。通常我们可以使用 类型断言 来测试在某个时刻 varI 是否包含类型 T 的值:

v := varI.(T)       // unchecked type assertion

varI 必须是一个接口变量,否则编译器会报错:invalid type assertion: varI.(T) (non-interface type (type of varI) on left) 。
类型断言可能是无效的,虽然编译器会尽力检查转换是否有效,但是它不可能预见所有的可能性。如果转换在程序运行时失败会导致错误发生。更安全的方式是使用以下形式来进行类型断言:

if v, ok := varI.(T); ok {  // checked type assertion
    Process(v)
    return
}
// varI is not of type T

如果转换合法,v 是 varI 转换到类型 T 的值,ok 会是 true;否则 v 是类型 T 的零值,ok 是 false,也没有运行时错误发生。
应该总是使用上面的方式来进行类型断言。
多数情况下,我们可能只是想在 if 中测试一下 ok 的值,此时使用以下的方法会是最方便的:

if _, ok := varI.(T); ok {
    // ...
}
``
例子
--

package main

import (
“fmt”
“math”
)

type Square struct {
side float32
}

type Circle struct {
radius float32
}

type Shaper interface {
Area() float32
}

func main() {
var areaIntf Shaper
sq1 := new(Square)
sq1.side = 5

areaIntf = sq1
// Is Square the type of areaIntf?
if t, ok := areaIntf.(*Square); ok {
    fmt.Printf("The type of areaIntf is: %T\n", t)
}
if u, ok := areaIntf.(*Circle); ok {
    fmt.Printf("The type of areaIntf is: %T\n", u)
} else {
    fmt.Println("areaIntf does not contain a variable of type Circle")
}

}

func (sq *Square) Area() float32 {
return sq.side * sq.side
}

func (ci *Circle) Area() float32 {
return ci.radius * ci.radius * math.Pi
}
“`

接口

The type of areaIntf is: *main.Square
areaIntf does not contain a variable of type Circle

程序行中定义了一个新类型 Circle,它也实现了 Shaper 接口。 t, ok := areaIntf.(*Square); ok 测试 areaIntf 里是否一个包含 ‘Square’ 类型的变量,结果是确定的;然后我们测试它是否包含一个 ‘Circle’ 类型的变量,结果是否定的。

转载地址

https://github.com/Unknwon/the-way-to-go_ZH_CN/blob/master/eBook/11.3.md

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值