为什么类型开关不允许穿透?

Kar*_*lek 21 go switch-statement

我想知道为什么在golang中的类型switch语句中不允许使用fallthrough.

根据规范:"类型切换中不允许使用"fallthrough"语句.",这并没有解释为什么不允许这样做.

附加的代码是模拟一个可能的场景,类型转换语句中的一个漏洞可能是有用的.

注意!这段代码不起作用,会产生错误:"无法通过类型切换".我只是想知道在类型切换中不允许使用fallthrough语句可能有什么原因.

//A type switch question
package main

import "fmt"

//Why isn't fallthrough in type switch allowed?
func main() {
    //Empty interface
    var x interface{}

    x = //A int, float64, bool or string value

    switch i := x.(type) {
    case int:
        fmt.Println(i + 1)
    case float64:
        fmt.Println(i + 2.0)
    case bool:
        fallthrough
    case string:
        fmt.Printf("%v", i)
    default:
        fmt.Println("Unknown type. Sorry!")
    }
}
Run Code Online (Sandbox Code Playgroud)

Lil*_*ard 34

你期望fallthrough如何工作?在此类型开关中,i变量的类型取决于调用的特定情况.所以在case booli变量的类型为bool.但在case string它的输入中string.所以要么你要求i神奇地改变它的类型,这是不可能的,或者你要求它被一个新的变量遮蔽,这个新的变量i string没有价值,因为它的价值来自x哪个不是,实际上,a string.


这是一个试图说明问题的例子:

switch i := x.(type) {
case int:
    // i is an int
    fmt.Printf("%T\n", i); // prints "int"
case bool:
    // i is a bool
    fmt.Printf("%T\n", i); // prints "bool"
    fallthrough
case string:
    fmt.Printf("%T\n", i);
    // What does that type? It should type "string", but if
    // the type was bool and we hit the fallthrough, what would it do then?
}
Run Code Online (Sandbox Code Playgroud)

唯一可能的解决方案是使fallthrough原因使后续的case表达式保留iinterface{},但这将是一个令人困惑和错误的定义.

如果您确实需要此行为,则可以使用现有功能完成此操作:

switch i := x.(type) {
case bool, string:
    if b, ok := i.(bool); ok {
        // b is a bool
    }
    // i is an interface{} that contains either a bool or a string
}
Run Code Online (Sandbox Code Playgroud)

  • @Mandarin:如果`i`是`bool`,如果`i`是`string`编译的代码可能无法编译.您不能编写处理一个变量的代码,就好像它有两个不同的类型.那么在`case bool`中我会有什么类型的?它当然不能是`bool`,如果它是`string`那么你必须丢弃'i`在`case bool`中的值,没有值,你的代码就没用了. (2认同)