类型断言从接口值中提取具体类型,类型开关根据接口的底层类型进行分支。这些是你从接口(尤其是空接口 / any)中恢复特定类型信息的方式。
类型断言 — 提取具体类型
go
i {} =
s := i.()
fmt.Println(s)
n := i.()
i.(Type) 语法断言接口 i 持有 Type 类型的值并将其提取出来。但错误的断言会 panic — 所以通常你使用安全的 comma-ok 形式。
s, ok := i.(string)
if ok {
fmt.Println("it's a string:", s) // ok = true, s = the value
} else {
fmt.Println("not a string") // ok = false, s = zero value, NO panic
}
两值形式返回值加一个布尔值 — 如果断言失败,ok 为假(而不是 panic)。除非你确定类型,否则始终优先使用这种形式。
func describe(i interface{}) string {
switch v := i.(type) { // the special .(type) form, only in a switch
case int:
return fmt.Sprintf("int: %d (doubled: %d)", v, v*2)
case string:
return fmt.Sprintf("string of length %d", len(v))
case bool:
return fmt.Sprintf("bool: %t", v)
case nil:
return "nil value"
default:
return fmt.Sprintf("unknown type: %T", v)
}
}
describe(42) // "int: 42 (doubled: 84)"
describe("hi") // "string of length 2"
switch v := i.(type) 形式检查底层类型并绑定 v(在每个 case 中适当地被类型化)。这是处理可能包含多种类型的接口的简洁方式。
// assert that a value implements a specific interface
if w, ok := i.(io.Writer); ok {
w.Write([]byte("data")) // use it as an io.Writer if it satisfies that interface
}
✓ Processing values of unknown type (interface{}/any) — JSON, generic handlers
✓ Checking if a value implements an optional interface (e.g. io.Closer)
✓ Handling heterogeneous data
⚠️ Often a sign you could use generics or better-typed interfaces instead — don't overuse
类型断言和类型开关是处理接口值的必要工具 — 从 interface{}/any 中恢复具体类型信息或检查值是否满足特定接口。
当处理类型未知或多种的数据时需要这些(解析动态 JSON、通用处理、可选接口检查如