?# 11.4 類型判斷:type-switch
接口變量的類型也可以使用一種特殊形式的 switch
來檢測:type-switch (下面是示例 11.4 的第二部分):
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
除外)都必須實(shí)現(xiàn)對應(yīng)的接口(在上例中即 Shaper
),如果被檢測類型沒有在 case
語句列舉的類型中,就會執(zhí)行 default
語句。
可以用 type-switch
進(jìn)行運(yùn)行時類型分析,但是在 type-switch
不允許有 fallthrough
。
如果僅僅是測試變量的類型,不用它的值,那么就可以不需要賦值語句,比如:
switch areaIntf.(type) {
case *Square:
// TODO
case *Circle:
// TODO
...
default:
// TODO
}
下面的代碼片段展示了一個類型分類函數(shù),它有一個可變長度參數(shù),可以是任意類型的數(shù)組,它會根據(jù)數(shù)組元素的實(shí)際類型執(zhí)行不同的動作:
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)
}
}
}
可以這樣調(diào)用此方法:classifier(13, -14.3, "BELGIUM", complex(1, 2), nil, false)
。
在處理來自于外部的、類型未知的數(shù)據(jù)時,比如解析諸如 JSON 或 XML 編碼的數(shù)據(jù),類型測試和轉(zhuǎn)換會非常有用。
在示例 12.17(xml.go)中解析 XML 文檔時,我們就會用到 type-switch
。
練習(xí) 11.4 simple_interface2.go:
接著練習(xí) 11.1 中的內(nèi)容,創(chuàng)建第二個類型 RSimple
,它也實(shí)現(xiàn)了接口 Simpler
,寫一個函數(shù) fi
,使它可以區(qū)分 Simple
和 RSimple
類型的變量。