061-类型开关(Type Switch)

Posted --Allen--

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了061-类型开关(Type Switch)相关的知识,希望对你有一定的参考价值。

这一篇仍然是与类型断言相关的,只是稍微再延伸一下。没事,不要怕,没你想象的复杂。

到目前为止,关于接口我们已经掌握了它的两种使用方法:

  • 实现了同一个接口的不同具体类型都具有共性特征,而接口屏蔽了底层细节。此时我们的关注的是接口的『方法』,而不是类型。
  • 使用类型断言,我们可以判断接口值的类型。此时我们关注的是接口的『类型』和『值』,而不是方法。

第二种方法通常被描述为 discriminated unions,它在计算机英语里是常见的术语,不知道怎么翻译。简单的说,接口是一种存放对象和对象所属类型标记的一种数据结构,即 discriminated unions,你可以叫它『标识联合』、『可辨识联合』随你了。

1. 类型开关(Type Switch)

通常我们可能会有一连串的 if … else 结构来判断接口类型,以便于做出不同的决策:

var e interface
// e = ... 

if e == nil 
    // ...
 else if v, ok := e.(int); ok 
    // ...
 else if v, ok := e.(float32); ok 
    // ...
 else if v, ok := e.(string); ok 
    // ...
 else if v, ok := e.(bool); ok 
    // ...

如果每次都这样写,相当费劲。Golang 关键字 swtich 支持一种非常便捷的写法,你可以这样:

var e interface
// e = ... 

switch v := e.(type) 
case nil:
    // ...
case int, uint, int32, uint32:
    // ...
case string:
    // ...
case bool:
    // ...
default:
    // ...

注意上面的语法:e.(type) 只能用在 switch 关键字后面,它会返回 e 接口中的值部分。当然你可以完全忽略 e.(type) 返回的值:

switch e.(type) 
case nil:
// ...

下面是一个非常简单的例子:

package main

import (
    "fmt"
    "io"
    "os"
)

func show(e interface) 
    switch v := e.(type) 
    case nil:
        fmt.Printf("Don't input nil\\n")
    case int, uint, int32, uint32, float32, float64:
        fmt.Printf("This is a number: %v\\n", v)
    case string:
        fmt.Printf("This is a string: %s\\n", v)
    case bool:
        fmt.Printf("This is a boolean: %v\\n", v)
    case io.Writer:
        fmt.Printf("This is a writer: %T\\n", v)
    case *os.File:
        fmt.Printf("This is a *os.File\\n")
    default:
        fmt.Printf("I don't know what it is\\n")
    


func main() 
    show(5)                     // This is a number: 5
    show("hello world")         // This is a string: hello world
    show(true)                  // This is a boolean: true
    show(5.6)                   // This is a number: 5.6
    show(os.Stdout)             // This is a writer: *os.File
    show([]int1 2 3 4)   // I don't know what it is

上面需要特别注意的是,case 后面你可以断言 e.(type) 是某种接口类型,就像 case io.Writer 一样。

尽管 os.Stdout*os.File 类型,但是由于 case io.Writer 写在 case *os.File 前面,所以 case *os.File 后面的语句就不会执行了。

2. 总结

  • 掌握 type switch 语法

以上是关于061-类型开关(Type Switch)的主要内容,如果未能解决你的问题,请参考以下文章

Go-动态类型与类型断言详解(含type-switch及全部代码)

golang 接口interface{}断言switch type

微信小程序把玩(二十一)switch组件

go语言学习笔记 — 进阶 — 接口:使用类型分支,批量判断空接口中变量的类型

在 switch 块中使用 QVariant::Type 的用户类型的 GCC 警告

如何打开Type