英文:
Why isn't fallthrough allowed in a type switch?
问题
我想知道为什么在golang的类型switch语句中不允许使用fallthrough。
根据规范:“在类型switch中不允许使用“fallthrough”语句。”,这并没有解释为什么不允许。
附上的代码是为了模拟可能需要在类型switch语句中使用fallthrough的情况。
**注意!**这段代码无法运行,会产生错误:“无法在类型switch中使用fallthrough”。我只是想知道为什么不允许在类型switch中使用fallthrough语句的可能原因。
//一个类型switch的问题
package main
import "fmt"
//为什么不允许在类型switch中使用fallthrough?
func main() {
//空接口
var x interface{}
x = //一个int、float64、bool或string值
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("未知类型。抱歉!")
}
}
英文:
I'm wondering why fallthrough isn't allowed in a type switch statement in golang.
According to the specification: "The "fallthrough" statement is not permitted in a type switch.", which doesn't explain much about WHY it isn't allowed.
The code attached is to simulate a possible scenario were a fallthrough in a type switch statement might have been useful.
Notice! This code doesn't work, it will produce the error: "cannot fallthrough in type switch". I'm just wondering what possible reasons might have been for not allowing the fallthrough statement in a type switch.
//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!")
}
}
答案1
得分: 48
你希望fallthrough
如何工作?在这个类型开关中,i
变量的类型取决于所调用的特定情况。所以在case bool
中,i
变量的类型是bool
。但在case string
中,它的类型是string
。所以要么你希望i
魔法般地改变它的类型,这是不可能的,要么你希望它被一个新的变量i string
遮蔽,但它没有值,因为它的值来自于x
,而x
实际上不是一个string
。
这里有一个示例来试图说明这个问题:
switch i := x.(type) {
case int:
// i是一个int
fmt.Printf("%T\n", i); // 输出 "int"
case bool:
// i是一个bool
fmt.Printf("%T\n", i); // 输出 "bool"
fallthrough
case string:
fmt.Printf("%T\n", i);
// 这个类型是什么?它应该是 "string",但如果类型是bool并且我们遇到了fallthrough,那么它会怎么做呢?
}
唯一可能的解决方案是让fallthrough
导致后续的case表达式将i
保持为interface{}
,但这将是一个令人困惑和糟糕的定义。
如果你真的需要这种行为,你可以通过现有的功能来实现:
switch i := x.(type) {
case bool, string:
if b, ok := i.(bool); ok {
// b是一个bool
}
// i是一个包含bool或string的interface{}
}
英文:
How would you expect fallthrough
to work? In this type switch, the i
variable has a type that depends on the particular case that's invoked. So in the case bool
the i
variable is typed as bool
. But in case string
it's typed as string
. So either you're asking for i
to magically morph its type, which isn't possible, or you're asking for it to be shadowed by a new variable i string
, which will have no value because its value comes from x
which is not, in fact, a string
.
Here's an example to try and illustrate the problem:
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?
}
The only possible solution would be to make the fallthrough
cause the subsequent case expression to leave i
as an interface{}
, but that would be a confusing and bad definition.
If you really need this behavior you can already accomplish this with the existing functionality:
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
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论