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



我想知道为什么在 golang 的类型切换语句中不允许 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!")
    }
}

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


下面是一个示例来尝试说明问题:

switch i := x.(type) {
case int:
    // i is an int
    fmt.Printf("%Tn", i); // prints "int"
case bool:
    // i is a bool
    fmt.Printf("%Tn", i); // prints "bool"
    fallthrough
case string:
    fmt.Printf("%Tn", 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?
}

唯一可能的解决方案是使fallthrough导致后续的 case 表达式将 i 保留为interface{},但这将是一个令人困惑和糟糕的定义。

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

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
}

最新更新