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.)
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…