Files
the-way-to-go_ZH_CN/eBook/11.4.md
htlhenry 685a7580da fix 拼写错误
fix switch拼写错误
2017-01-20 18:35:05 +08:00

78 lines
2.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 11.4 类型判断type-switch
接口变量的类型也可以使用一种特殊形式的 `switch` 来检测:**type-switch** (下面是示例 11.4 的第二部分):
```go
switch t := areaIntf.(type) {
case *Square:
fmt.Printf("Type Square %T with value %v\n", t, t)
case *Circle:
fmt.Printf("Type Circle %T with value %v\n", t, t)
case nil:
fmt.Printf("nil value: nothing to check?\n")
default:
fmt.Printf("Unexpected type %T\n", t)
}
```
输出:
Type Square *main.Square with value &{5}
变量 `t` 得到了 `areaIntf` 的值和类型, 所有 `case` 语句中列举的类型(`nil` 除外)都必须实现对应的接口(在上例中即 `Shaper`),如果被检测类型没有在 `case` 语句列举的类型中,就会执行 `default` 语句。
可以用 `type-switch` 进行运行时类型分析,但是在 `type-switch` 不允许有 `fallthrough`
如果仅仅是测试变量的类型,不用它的值,那么就可以不需要赋值语句,比如:
```go
switch areaIntf.(type) {
case *Square:
// TODO
case *Circle:
// TODO
...
default:
// TODO
}
```
下面的代码片段展示了一个类型分类函数,它有一个可变长度参数,可以是任意类型的数组,它会根据数组元素的实际类型执行不同的动作:
```go
func classifier(items ...interface{}) {
for i, x := range items {
switch x.(type) {
case bool:
fmt.Printf("Param #%d is a bool\n", i)
case float64:
fmt.Printf("Param #%d is a float64\n", i)
case int, int64:
fmt.Printf("Param #%d is a int\n", i)
case nil:
fmt.Printf("Param #%d is a nil\n", i)
case string:
fmt.Printf("Param #%d is a string\n", i)
default:
fmt.Printf("Param #%d is unknown\n", i)
}
}
}
```
可以这样调用此方法:`classifier(13, -14.3, "BELGIUM", complex(1, 2), nil, false)`
在处理来自于外部的、类型未知的数据时,比如解析诸如 JSON 或 XML 编码的数据,类型测试和转换会非常有用。
在示例 12.17xml.go中解析 XML 文档时,我们就会用到 `type-switch`
**练习 11.4** simple_interface2.go
接着练习 11.1 中的内容,创建第二个类型 `RSimple`,它也实现了接口 `Simpler`,写一个函数 `fi`,使它可以区分 `Simple``RSimple` 类型的变量。
## 链接
- [目录](directory.md)
- 上一节:[类型断言:如何检测和转换接口变量的类型](11.3.md)
- 下一节:[测试一个值是否实现了某个接口](11.5.md)