如果你熟悉面向?qū)ο缶幊蹋憧赡軙⑦@兩種方式當作是subtype polymorphism(子類型多態(tài))和 ad hoc polymorphism(非參數(shù)多態(tài)),但是你不需要去記住這些術(shù)語。對于本章剩下的部分,我們將會呈現(xiàn)一些第二種方式的例子。
import "database/sql"
func listTracks(db sql.DB, artist string, minYear, maxYear int) {
result, err := db.Exec(
"SELECT * FROM tracks WHERE artist = ? AND ? <= year AND year <= ?",
artist, minYear, maxYear)
// ...
}
func sqlQuote(x interface{}) string {
if x == nil {
return "NULL"
} else if _, ok := x.(int); ok {
return fmt.Sprintf("%d", x)
} else if _, ok := x.(uint); ok {
return fmt.Sprintf("%d", x)
} else if b, ok := x.(bool); ok {
if b {
return "TRUE"
}
return "FALSE"
} else if s, ok := x.(string); ok {
return sqlQuoteString(s) // (not shown)
} else {
panic(fmt.Sprintf("unexpected type %T: %v", x, x))
}
}
在最簡單的形式中,一個類型分支像普通的switch語句一樣,它的運算對象是x.(type)——它使用了關(guān)鍵詞字面量type——并且每個case有一到多個類型。一個類型分支基于這個接口值的動態(tài)類型使一個多路分支有效。這個nil的case和if x == nil匹配,并且這個default的case和如果其它case都不匹配的情況匹配。一個對sqlQuote的類型分支可能會有這些case:
switch x.(type) {
case nil: // ...
case int, uint: // ...
case bool: // ...
case string: // ...
default: // ...
}
func sqlQuote(x interface{}) string {
switch x := x.(type) {
case nil:
return "NULL"
case int, uint:
return fmt.Sprintf("%d", x) // x has type interface{} here.
case bool:
if x {
return "TRUE"
}
return "FALSE"
case string:
return sqlQuoteString(x) // (not shown)
default:
panic(fmt.Sprintf("unexpected type %T: %v", x, x))
}
}
更多建議: