defs:
形如 res,ok:=x.(T) 的表达式为类型断言,其中 x 必须是接口(空接口亦可),T 可以是接口或具体类型, ok 表示断言是否成功,若成功则 res 的值为 x 的值,类型为 x 的类型,否则 panic。
case 1:x is nil,会 panic
var x interface{} = nil
fmt.Print(x.(int))
case 2:T is type,若 T 与原类型一致,则断言成功,否则失败
example 1:
var x interface{} = 1
fmt.Println("x 的真实类型:", reflect.TypeOf(x))
if res, ok := x.(int); ok {
fmt.Println("断言成功,res 的值为", res)
}
if res, ok := x.(string); !ok {
fmt.Println("断言失败,res 的值即为默认值(无效值)", res)
}
example 2:
var w io.Writer = os.Stdout // os.Stdout 为 *os.File 类型,实现了 io.Writer
f := w.(*os.File) // success: f == os.Stdout
c := w.(*bytes.Buffer) // panic: interface holds *os.File, not *bytes.Buffer
case 3: T is interface ,则判断 x 是否实现了 T 接口
example 1:
package main
import (
"fmt"
"reflect"
)
type Runner interface {
run()
}
type Flyer interface {
fly()
}
type RunnerFlyer interface {
Runner
Flyer
}
type Person struct {}
type Chicken struct {}
func (*Chicken) run() {}
func (*Chicken) fly() {}
func (*Person) run() {}
func main() {
var x Runner = &Chicken{}
res, ok := x.(Flyer)
fmt.Printf("断言:%v,res 的类型:%v:\n", ok, reflect.TypeOf(res))
//断言:true,res 的类型:*main.Chicken:
x = &Person{}
res, ok = x.(Flyer)
fmt.Printf("断言:%v,res 的类型:%v:", ok, reflect.TypeOf(res))
//断言:false,res 的类型:<nil>:
var rf RunnerFlyer = &Chicken{}
v, ok := rf.(Flyer)
v.fly() //ok
v.run() //can't use run
}
example 2:
var w io.Writer
w = os.Stdout
rw := w.(io.ReadWriter) // success: *os.File has both Read and Write
w = new(strings.Builder)
rw := w.(io.ReadWriter) // panic: *strings.Builder has no Read method