Type assertions and type switches in GO

    科技2022-08-08  120

    Type assertions and type switches in GO

    Type assertions and type switches in GO Type assertionsType switches类型转换和类型断言有什么不同?如果x.(T)中的T为interface{}而不是一个确切的类型,x.(T)会返回什么?

    使用类型断言是为了访问接口的具体值。

    Type assertions

    类型断言并不会真正将接口转换为另一种数据类型,但是可以访问接口的具体值。

    x.(T)断言x不是nil,且存储在x中的值是T类型。

    使用类型断言的返回值:

    t := x.(T) => t 需要为 T类型; 如果 x 为 nil,会发生错误。t,ok := x.(T) => 如果x为nil或不等于T类型,则ok为false。至于t,与上一例相同。

    简单用法:

    var x interface{} = "foo" var s string = x.(string) fmt.Println(s) // "foo" s, ok := x.(string) fmt.Println(s, ok) // "foo true" n, ok := x.(int) fmt.Println(n, ok) // "0 false" n = x.(int) // ILLEGAL // panic: interface conversion: interface {} is string, not int

    Type switches

    Type switches 用于匹配类型。

    简单用法:

    var x interface{} = "foo" switch v := x.(type) { case nil: fmt.Println("x is nil") case int: fmt.Println("x is int") case bool, string: fmt.Println("x is bool or string") default: fmt.Println("type unknown") } // x is bool or string

    类型转换和类型断言有什么不同?

    类型转换将一种(非接口)类型转换为另一种类型而类型断言只是判断它的类型

    如果必须将具体类型包装到接口中并希望返回具体类型,请使用类型断言assertions(或类型切换switches)。如果需要将一种具体类型转换为另一种具体类型,请使用类型转换。

    如果x.(T)中的T为interface{}而不是一个确切的类型,x.(T)会返回什么?

    能够正常运行,返回结果如下:

    package main import "fmt" func main() { var i interface{} // nil b, ok := i.(interface{}) fmt.Println(b, ok) // <nil> false i = 2 c, ok := i.(interface{}) fmt.Println(c, ok) // 2 true // 不能使用c给int的j赋值,原因是c是interface{}类型而不是int // var j int = c }

    详细示例:

    package main import "fmt" func main() { const fm = "'%T'\t'%#[1]v'\t'%[1]v'\t%v\n" var i interface{} b, ok := i.(interface{}) fmt.Printf(fm, b, ok) // '<nil>' '<nil>' '<nil>' false i = 2 b, ok = i.(interface{}) fmt.Printf(fm, b, ok) // 'int' '2' '2' true i = "Hi" b, ok = i.(interface{}) fmt.Printf(fm, b, ok) // 'string' '"Hi"' 'Hi' true i = new(interface{}) b, ok = i.(interface{}) fmt.Printf(fm, b, ok) // '*interface {}' '(*interface {})(0xc042004330)' '0xc042004330' true i = struct{}{} b, ok = i.(interface{}) fmt.Printf(fm, b, ok) // 'struct {}' 'struct {}{}' '{}' true i = fmt.Println b, ok = i.(interface{}) fmt.Printf(fm, b, ok) // 'func(...interface {}) (int, error)' '(func(...interface {}) (int, error))(0x456740)' '0x456740' true i = Shape.Area b, ok = i.(interface{}) fmt.Printf(fm, b, ok) // 'func(main.Shape) float64' '(func(main.Shape) float64)(0x401910)' '0x401910' true } type Shape interface { Area() float64 }
    Processed: 0.025, SQL: 9