2012-07-17 14 views
13

Me pregunto por qué Fallthrough no está permitido en una declaración de cambio de tipo en golang.¿Por qué no se permite la transición en un cambio de tipo?

De acuerdo con specification: "La instrucción" fallthrough "no está permitida en un modificador de tipo", lo que no explica mucho acerca de POR QUÉ no está permitido.

El código adjunto es para simular un posible escenario donde una caída en una declaración de cambio de tipo podría haber sido útil.

Aviso! Este código no funciona, producirá el error: "no puede fallar en el cambio de tipo". Me pregunto qué posibles razones podrían haber sido para no permitir la declaración de caída en un cambio de tipo.

//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!") 
    } 
} 

Respuesta

29

¿Cómo cabría esperar fallthrough para trabajar? En este modificador de tipo, la variable i tiene un tipo que depende del caso particular que se invoca. Por lo tanto, en el case bool, la variable i se escribe como bool. Pero en case string está escrito como string. Entonces, o bien está pidiendo i para cambiar mágicamente su tipo, lo cual no es posible, o está pidiendo que lo sombree una nueva variable i string, que no tendrá valor porque su valor proviene de x que no es , de hecho, un string.


He aquí un ejemplo para tratar de ilustrar el problema:

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? 
} 

La única solución posible sería la de hacer que el fallthrough causa la expresión caso posterior a abandonar i como interface{}, pero eso sería una definición confusa y mala

Si realmente necesita este comportamiento ya se puede lograr esto con la funcionalidad existente:

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 
} 
+0

@KevinBallard, mi mal. – Ben

+0

Gracias por la explicación, pero debo admitir que realmente no entiendo por qué fmt.Printf ("% T \ n", i) no imprimiría "bool" de nuevo. Debido a que en una caída regular, la declaración de caso se ignora y la expresión es de tipo inconsciente. Probablemente sea porque lo estoy relacionando mucho con una declaración de cambio regular que me resulta difícil descifrar esto. – Karlek

+2

@Mandarin: El código que compila si 'i' es' cadena' no puede compilarse si 'i' es' bool'. No puede escribir código que trate una variable como si tuviera dos tipos separados. Entonces, ¿qué tipo tendría 'i' en el' caso bool'? Ciertamente no puede ser 'bool', y si es 'cadena', entonces necesariamente debe descartar el valor que' i' tenía en 'case bool', y sin el valor de su código es bastante inútil. –

Cuestiones relacionadas