Подтвердить что ты не робот

Почему в переключателе типа не разрешено прохождение?

Мне интересно, почему провал не разрешен в выражении оператора типа в golang.

В соответствии с спецификацией: "Операция" проскальзывание "не допускается при переключении типа.", что мало объясняет, почему нет допускается.

Приведенный код заключается в том, чтобы имитировать возможный сценарий, поскольку прохождение в инструкции типа switch могло бы быть полезным.

Обратите внимание! Этот код не работает, он выдает ошибку: "не может пройти через переключатель типа". Мне просто интересно, какие возможные причины могут быть связаны с тем, что вы не допустили утверждение 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!")
    }
}
4b9b3361

Ответ 1

Как бы вы ожидали, что fallthrough будет работать? В этом типе переменная i имеет тип, зависящий от конкретного вызванного случая. Таким образом, в case bool переменная i вводится как 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?
}

Единственное возможное решение состоит в том, чтобы заставить 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
}