为什么在类型切换中不允许使用fallthrough?

huangapple go评论110阅读模式
英文:

Why isn't fallthrough allowed in a type switch?

问题

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

根据规范:“在类型switch中不允许使用“fallthrough”语句。”,这并没有解释为什么不允许。

附上的代码是为了模拟可能需要在类型switch语句中使用fallthrough的情况。

**注意!**这段代码无法运行,会产生错误:“无法在类型switch中使用fallthrough”。我只是想知道为什么不允许在类型switch中使用fallthrough语句的可能原因。

  1. //一个类型switch的问题
  2. package main
  3. import "fmt"
  4. //为什么不允许在类型switch中使用fallthrough?
  5. func main() {
  6. //空接口
  7. var x interface{}
  8. x = //一个int、float64、bool或string值
  9. switch i := x.(type) {
  10. case int:
  11. fmt.Println(i + 1)
  12. case float64:
  13. fmt.Println(i + 2.0)
  14. case bool:
  15. fallthrough
  16. case string:
  17. fmt.Printf("%v", i)
  18. default:
  19. fmt.Println("未知类型。抱歉!")
  20. }
  21. }
英文:

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.

  1. //A type switch question
  2. package main
  3. import "fmt"
  4. //Why isn't fallthrough in type switch allowed?
  5. func main() {
  6. //Empty interface
  7. var x interface{}
  8. x = //A int, float64, bool or string value
  9. switch i := x.(type) {
  10. case int:
  11. fmt.Println(i + 1)
  12. case float64:
  13. fmt.Println(i + 2.0)
  14. case bool:
  15. fallthrough
  16. case string:
  17. fmt.Printf("%v", i)
  18. default:
  19. fmt.Println("Unknown type. Sorry!")
  20. }
  21. }

答案1

得分: 48

你希望fallthrough如何工作?在这个类型开关中,i变量的类型取决于所调用的特定情况。所以在case bool中,i变量的类型是bool。但在case string中,它的类型是string。所以要么你希望i魔法般地改变它的类型,这是不可能的,要么你希望它被一个新的变量i string遮蔽,但它没有值,因为它的值来自于x,而x实际上不是一个string

这里有一个示例来试图说明这个问题:

  1. switch i := x.(type) {
  2. case int:
  3. // i是一个int
  4. fmt.Printf("%T\n", i); // 输出 "int"
  5. case bool:
  6. // i是一个bool
  7. fmt.Printf("%T\n", i); // 输出 "bool"
  8. fallthrough
  9. case string:
  10. fmt.Printf("%T\n", i);
  11. // 这个类型是什么?它应该是 "string",但如果类型是bool并且我们遇到了fallthrough,那么它会怎么做呢?
  12. }

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

如果你真的需要这种行为,你可以通过现有的功能来实现:

  1. switch i := x.(type) {
  2. case bool, string:
  3. if b, ok := i.(bool); ok {
  4. // b是一个bool
  5. }
  6. // i是一个包含bool或string的interface{}
  7. }
英文:

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:

  1. switch i := x.(type) {
  2. case int:
  3. // i is an int
  4. fmt.Printf("%T\n", i); // prints "int"
  5. case bool:
  6. // i is a bool
  7. fmt.Printf("%T\n", i); // prints "bool"
  8. fallthrough
  9. case string:
  10. fmt.Printf("%T\n", i);
  11. // What does that type? It should type "string", but if
  12. // the type was bool and we hit the fallthrough, what would it do then?
  13. }

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:

  1. switch i := x.(type) {
  2. case bool, string:
  3. if b, ok := i.(bool); ok {
  4. // b is a bool
  5. }
  6. // i is an interface{} that contains either a bool or a string
  7. }

huangapple
  • 本文由 发表于 2012年7月18日 05:39:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/11531264.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定