|
@@ -1,46 +1,45 @@
|
|
|
# 11.4 类型判断:type-switch
|
|
# 11.4 类型判断:type-switch
|
|
|
|
|
|
|
|
-接口变量的类型也可以使用一种特殊形式的 `swtich` 来检测:**type-swtich** (下面是 示例 11.4 的第二部分):
|
|
|
|
|
|
|
+接口变量的类型也可以使用一种特殊形式的 `swtich` 来检测:**type-swtich** (下面是示例 11.4 的第二部分):
|
|
|
|
|
|
|
|
```go
|
|
```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)
|
|
|
|
|
- }
|
|
|
|
|
|
|
+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}
|
|
Type Square *main.Square with value &{5}
|
|
|
|
|
|
|
|
-变量 `t` 得到了 `areaIntf` 的值和类型, 所有 `case` 语句中列举的类型(`nil` 除外)都必须实现对应的接口(在上例中即 `Shaper`),如果被检测类型没有在 `case` 语句列举的类型中,就会执行`default` 语句。
|
|
|
|
|
|
|
+变量 `t` 得到了 `areaIntf` 的值和类型, 所有 `case` 语句中列举的类型(`nil` 除外)都必须实现对应的接口(在上例中即 `Shaper`),如果被检测类型没有在 `case` 语句列举的类型中,就会执行 `default` 语句。
|
|
|
|
|
|
|
|
可以用 `type-switch` 进行运行时类型分析,但是在 `type-switch` 不允许有 `fallthrough` 。
|
|
可以用 `type-switch` 进行运行时类型分析,但是在 `type-switch` 不允许有 `fallthrough` 。
|
|
|
|
|
|
|
|
如果仅仅是测试变量的类型,不用它的值,那么就可以不需要赋值语句,比如:
|
|
如果仅仅是测试变量的类型,不用它的值,那么就可以不需要赋值语句,比如:
|
|
|
|
|
|
|
|
```go
|
|
```go
|
|
|
- switch areaIntf.(type) {
|
|
|
|
|
- case *Square:
|
|
|
|
|
- // TODO
|
|
|
|
|
- case *Circle:
|
|
|
|
|
- // TODO
|
|
|
|
|
- ...
|
|
|
|
|
- default:
|
|
|
|
|
- // TODO
|
|
|
|
|
- }
|
|
|
|
|
|
|
+switch areaIntf.(type) {
|
|
|
|
|
+case *Square:
|
|
|
|
|
+ // TODO
|
|
|
|
|
+case *Circle:
|
|
|
|
|
+ // TODO
|
|
|
|
|
+...
|
|
|
|
|
+default:
|
|
|
|
|
+ // TODO
|
|
|
|
|
+}
|
|
|
```
|
|
```
|
|
|
|
|
|
|
|
下面的代码片段展示了一个类型分类函数,它有一个可变长度参数,可以是任意类型的数组,它会根据数组元素的实际类型执行不同的动作:
|
|
下面的代码片段展示了一个类型分类函数,它有一个可变长度参数,可以是任意类型的数组,它会根据数组元素的实际类型执行不同的动作:
|
|
|
|
|
|
|
|
```go
|
|
```go
|
|
|
-
|
|
|
|
|
func classifier(items ...interface{}) {
|
|
func classifier(items ...interface{}) {
|
|
|
for i, x := range items {
|
|
for i, x := range items {
|
|
|
switch x.(type) {
|
|
switch x.(type) {
|
|
@@ -65,11 +64,11 @@ func classifier(items ...interface{}) {
|
|
|
|
|
|
|
|
在处理来自于外部的、类型未知的数据时,比如解析诸如 JSON 或 XML 编码的数据,类型测试和转换会非常有用。
|
|
在处理来自于外部的、类型未知的数据时,比如解析诸如 JSON 或 XML 编码的数据,类型测试和转换会非常有用。
|
|
|
|
|
|
|
|
-在 示例12.17(xml.go) 中解析 XML 文档是,我们就会用到 `type-switch` 。
|
|
|
|
|
|
|
+在示例 12.17(xml.go)中解析 XML 文档时,我们就会用到 `type-switch`。
|
|
|
|
|
|
|
|
**练习 11.4** simple_interface2.go:
|
|
**练习 11.4** simple_interface2.go:
|
|
|
|
|
|
|
|
-接着 练习11.1 中的内容,创建第二个类型 `RSimple`,它也实现了接口 `Simpler`,写一个函数 `fi`,它可以区分 `Simple` 和 `RSimple` 类型的变量。
|
|
|
|
|
|
|
+接着练习 11.1 中的内容,创建第二个类型 `RSimple`,它也实现了接口 `Simpler`,写一个函数 `fi`,使它可以区分 `Simple` 和 `RSimple` 类型的变量。
|
|
|
|
|
|
|
|
## 链接
|
|
## 链接
|
|
|
|
|
|