跳到主要内容

Go语法-类型判断

Type Switch

var t interface{}
t = functionOfSomeType()
switch t := t.(type) {
default:
fmt.Printf("unexpected type %T\n", t) // %T prints whatever type t has
case bool:
fmt.Printf("boolean %t\n", t) // t has type bool
case int:
fmt.Printf("integer %d\n", t) // t has type int
case *bool:
fmt.Printf("pointer to boolean %t\n", *t) // t has type *bool
case *int:
fmt.Printf("pointer to integer %d\n", *t) // t has type *int
}

Type Assertion

Type Switch 使用了 type 标识符,如果我们只关心一种类型的话,可以使用确定 的 type 类型来替代 type 标识符,如 value.(typeName)

如果 interface{} 中不包含类型 typeName 就会报错。

简单例子

var i interface{}
i = int(42)

a, ok := i.(int)
// a == 42 and ok == true

b, ok := i.(string)
// b == "" (default value) and ok == false

复杂例子

type Stringer interface {
String() string
}

if str, ok := value.(string); ok {
return str
} else if str, ok := value.(Stringer); ok {
return str.String()
}

案例

由于历史原因或代码对接过程中没有做到统一数据类型

如出现下面两种类型

type Message struct {
Name string
Time string
}
type Message struct {
Name string
Time float64
}

处理的方式就是结合使用 interface{}type switch

type Message struct {
Name string
Time interface{}
}

b := []byte(`{"Name":"Wednesday","Time":6}`)

var f Message
json.Unmarshal(b, &f)

switch v := f.Time.(type) {
case float64:
fmt.Printf("Name: %v; Time: %v\n", f.Name, v)
fmt.Printf("Time type %T!\n", v)
case string:
fmt.Printf("Name: %v; Time: %v\n", f.Name, v)
fmt.Printf("Time type %T!\n", v)
default:
fmt.Printf("I don't know about type %T!\n", v)
}

参考:Golang Type switches