首页
技术小册
AIGC
面试刷题
技术文章
MAGENTO
云计算
视频课程
源码下载
PDF书籍
「涨薪秘籍」
登录
注册
接口是什么
接口嵌套接口
类型断言:如何检测和转换接口变量的类型
类型判断:type-switch
测试一个值是否实现了某个接口
使用方法集与接口
第一个例子:使用 Sorter 接口排序
第二个例子:读和写
空接口
反射包
Printf 和反射
接口与动态类型
总结:Go 中的面向对象
结构体、集合和高阶函数
读取用户的输入
文件读写
文件拷贝
从命令行读取参数
用 buffer 读取文件
用切片读写文件
用 defer 关闭文件
使用接口的实际例子:fmt.Fprintf
格式化 JSON 数据
XML 数据格式
用 Gob 传输数据
Go 中的密码学
错误处理
运行时异常和 panic
从 panic 中恢复(Recover)
自定义包中的错误处理和 panicking
一种用闭包处理错误的模式
启动外部命令和程序
Go 中的单元测试和基准测试
测试的具体例子
用(测试数据)表驱动测试
性能调试:分析并优化 Go 程序
什么是协程
协程间的信道
协程的同步:关闭通道-测试阻塞的通道
使用 select 切换协程
通道、超时和计时器(Ticker)
协程和恢复(recover)
新旧模型对比:任务和worker
惰性生成器的实现
实现 Futures 模式
复用
限制同时处理的请求数
链式协程
在多核心上并行计算
并行化大量数据的计算
漏桶算法
对Go协程进行基准测试
使用通道并发访问对象
tcp服务器
一个简单的网页服务器
访问并读取页面
写一个简单的网页应用
确保网页应用健壮
用模板编写网页应用
探索 template 包
精巧的多功能网页服务器
用 rpc 实现远程过程调用
基于网络的通道 netchan
与 websocket 通信
用 smtp 发送邮件
当前位置:
首页>>
技术小册>>
go编程权威指南(三)
小册名称:go编程权威指南(三)
一个接口类型的变量 `varI` 中可以包含任何类型的值,必须有一种方式来检测它的 **动态** 类型,即运行时在变量中存储的值的实际类型。在执行过程中动态类型可能会有所不同,但是它总是可以分配给接口变量本身的类型。通常我们可以使用 **类型断言** 来测试在某个时刻 `varI` 是否包含类型 `T` 的值: ```go v := varI.(T) // unchecked type assertion ``` **`varI` 必须是一个接口变量**,否则编译器会报错:`invalid type assertion: varI.(T) (non-interface type (type of varI) on left)` 。 类型断言可能是无效的,虽然编译器会尽力检查转换是否有效,但是它不可能预见所有的可能性。如果转换在程序运行时失败会导致错误发生。更安全的方式是使用以下形式来进行类型断言: ```go 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` 的值,此时使用以下的方法会是最方便的: ```go if _, ok := varI.(T); ok { // ... } ``` 示例 11.4 ```go 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` 接口。 `if t, ok := areaIntf.(*Square); ok` 测试 `areaIntf` 里是否有一个包含 `*Square` 类型的变量,结果是确定的;然后我们测试它是否包含一个 `*Circle` 类型的变量,结果是否定的。 **备注** 如果忽略 `areaIntf.(*Square)` 中的 `*` 号,会导致编译错误:`impossible type assertion: Square does not implement Shaper (Area method has pointer receiver)`。
上一篇:
接口嵌套接口
下一篇:
类型判断:type-switch
该分类下的相关小册推荐:
Go-Web编程实战
WebRTC音视频开发实战
Go开发基础入门
Go开发权威指南(下)
go编程权威指南(二)
Go Web编程(下)
Go Web编程(上)
Golang修炼指南
Go开发权威指南(上)
深入浅出Go语言核心编程(六)
Go 组件设计与实现
Go语言入门实战经典