-
Notifications
You must be signed in to change notification settings - Fork 635
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
make all error enums extensible #969
Comments
Sorry for the silly question, but how would |
Because enums are frozen, which means that the Swift compiler verifies that switches over those enums are exhaustive. If we add an enum case, that will break some kinds of previously-exhaustive switch statements, which is a semver major. However, switch statements over equatable structs cannot be verified to be exhaustive, and so they enforce the use of a In the future the Swift team may bring |
@Lukasa thank you for the explanation! I was somehow thinking of user-extensible, not framework-extensible. Would have never thought that extending an enum would be a breaking change, but it makes total sense in this light. |
Big unsolved problem with public struct PizzaError: Error, Equatable, CustomStringConvertible {
private enum PizzaErrorCode: Equatable {
case unacceptableIngredient(String)
case tooCold
}
private var code: PizzaErrorCode
private init(code: PizzaErrorCode) {
self.code = code
}
public var description: String {
return "PizzaError.\(String(describing: self.code))"
}
public static func unacceptableIngredient(_ which: String) -> PizzaError {
return .init(code: .unacceptableIngredient(which))
}
public static let tooCold: PizzaError = .init(code: .tooCold)
}
let e1 = PizzaError.unacceptableIngredient("chicken")
let e2 = PizzaError.unacceptableIngredient("barbeque sauce")
let e3 = PizzaError.tooCold
let someError: PizzaError = [e1, e2, e3].randomElement()!
switch someError {
case .tooCold:
print("too cold!")
// // THIS DOES NOT WORK
// case .unacceptableIngredient(let foo):
// print("bad ingredient: \(foo)")
// THIS DOES WORK but is bad because we'd need to match the exact value
case .unacceptableIngredient("chicken"):
print("chicken doesn't belong on pizza")
default:
print("so picky: \(someError)")
}
// we can build `match*` or something properties that yield the associated
// values, but that's a lot of work and not very ergonomic to work with.
extension PizzaError {
var matchUnacceptableIngredient: String? {
switch self.code {
case .unacceptableIngredient(let which):
return which
default:
return nil
}
}
}
if let badIngredient = someError.matchUnacceptableIngredient {
print("\(badIngredient) on pizza is unacceptable")
} |
There are basically two options:
The text was updated successfully, but these errors were encountered: