golang类型断言

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 的类型:

    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

你可能感兴趣的:(go)