Swift switch语句考虑了所有Int的情况,但编译器仍然显示错误 [英] Swift switch statement considered all cases of Int, but compiler still display error

查看:285
本文介绍了Swift switch语句考虑了所有Int的情况,但编译器仍然显示错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我了解Swift中的switch语句必须是详尽无遗的,否则我们必须提供一个默认的情况。我看到下面的代码在线,switch语句已经涵盖了Int中的所有情况,但编译器仍然显示错误消息,切换必须是穷尽的,考虑添加一个默认子句。有没有我想要的东西?

  extension Int {
enum Kind {
case Negative,Zero ,Positive
}

var kind:Kind {
switch self {
case 0:
return .Zero
case let x where x > 0:
return .Positive
case let x其中x < 0:
return .Negative
}
}
}


解决方案

Swift 3更新 Swift 3引入了 ClosedRange ,这使
成为可能定义一个范围,如 1 ... Int.max 包括
最大可能的整数(比较 Swift 3中的范围)。所以这样编译并按预期工作,
,但仍然需要一个默认情况来满足编译器的需要:

  extension Int { 
enum Kind {
case negative,zero,positive
}
var kind:Kind {
switch self {
case 0:
return .zero
case 1 ... Int.max:
return .positive
case Int.min ...( - 1):
return .negative
default :
fatalError(糟糕,这不应该发生)
}
}
}

还有其他错误报告,其中Swift编译器不
正确地确定switch语句的详尽性,例如$ a
as https://bugs.swift.org/browse/SR-766 ,其中Apple工程师Joe Groff
评论: / p>


不幸的是,像'...'一样的整数运算nd'<'只是Swift的简单函数,所以很难做这种分析。即使特殊情况下理解整数间隔,我认为仍然存在完全一致的模式匹配的情况,穷举匹配将是不可判定的。我们可能最终可以处理一些案例,但总是会遇到特殊情况。







旧答案:编译器不太明智地认识到您已经覆盖了
所有可能的情况。一个可能的解决方案是添加一个默认的
案例,一个 fatalError()

  var kind:Kind {
switch self {
case 0:
return .Zero
case let x where x> 0:
return .Positive
case let x其中x < 0:
return .Negative
默认值:
fatalError(糟糕,这不应该发生)
}
}

或使 case 0:默认情况:

  var kind:Kind {
switch self {
case let x where x> 0:
return .Positive
case let x其中x < 0:
return .Negative
default:
return .Zero
}
}

备注:我最初认为以下内容可以正常工作
,而不需要默认情况:

  var kind:Kind {
switch self {
case 0:
return .Zero
case 1 ... Int .max:
return .Positive
case Int.min ... -1:
return .Negative
}
}

但是,这个编译,但在运行时中止,因为您不能
创建范围 1 ... Int.max 。有关这个
问题的更多信息可以在文章 Swift中的范围和间隔)。


I understand switch statement in Swift must be exhaustive, otherwise we have to provide an default case. I saw the code below online, the switch statement already have covered all cases in Int, but the compiler still display error message that switch must be exhaustive, consider adding a default clause. Is there something I'm missing?

extension Int {
    enum Kind {
        case Negative, Zero, Positive
    }

    var kind: Kind {
        switch self {
        case 0:
            return .Zero
        case let x where x > 0:
            return .Positive
        case let x where x < 0:
            return .Negative
        }
    }
}

解决方案

Update for Swift 3: Swift 3 introduced ClosedRange which makes it possible to define a range like 1...Int.max including the largest possible integer (compare Ranges in Swift 3). So this compiles and works as expected, but still requires a default case to satisfy the compiler:

extension Int {
    enum Kind {
        case negative, zero, positive
    }
    var kind: Kind {
        switch self {
        case 0:
            return .zero
        case 1...Int.max:
            return .positive
        case Int.min...(-1):
            return .negative
        default:
            fatalError("Oops, this should not happen")
        }
    }
}

There are other bug reports where the Swift compiler does not correctly determine the exhaustiveness of switch-statements, such as https://bugs.swift.org/browse/SR-766, where Apple engineer Joe Groff commented:

Unfortunately, integer operations like '...' and '<' are just plain functions to Swift, so it'd be difficult to do this kind of analysis. Even with special case understanding of integer intervals, I think there are still cases in the full generality of pattern matching for which exhaustiveness matching would be undecidable. We may eventually be able to handle some cases, but there will always be special cases involved in doing so.


Old answer: The compiler is not so smart to recognize that you have covered all possible cases. One possible solution is to add a default case with a fatalError():

var kind: Kind {
    switch self {
    case 0:
        return .Zero
    case let x where x > 0:
        return .Positive
    case let x where x < 0:
        return .Negative
    default:
        fatalError("Oops, this should not happen")
    }
}

Or make case 0: the default case:

var kind: Kind {
    switch self {
    case let x where x > 0:
        return .Positive
    case let x where x < 0:
        return .Negative
    default:
        return .Zero
    }
}

(Remark: I initially thought that the following would work correctly without needed a default case:

var kind: Kind {
    switch self {
    case 0:
        return .Zero
    case 1 ... Int.max:
        return .Positive
    case Int.min ... -1:
        return .Negative
    }
}

However, this compiles, but aborts at runtime because you cannot create the range 1 ... Int.max. More information around this problem can be found in the article Ranges and Intervals in Swift.)

这篇关于Swift switch语句考虑了所有Int的情况,但编译器仍然显示错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆