欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Type assertions and type switches in GO

程序员文章站 2024-02-27 13:54:21
...

Type assertions and type switches in GO

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

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
}
相关标签: 服务计算