Reputation: 4355
How can I access an enum value for a specific case without having to implement an enum function for each case?
I'm thinking something like this:
enum Result<S, F> {
case success(S)
case failure(F)
}
let resultSuccess = Result<Int, String>.success(1)
let resultFailure = Result<Int, String>.failure("Error")
let error: String? = case let .failure(error) = resultFailure
Something like this would also be acceptable:
let error: String? = (case let .failure(error) = resultFailure) ? error : ""
Obviously this doesn't even compile, but that's the gist of what I want.
Is that possible?
EDIT: explaining why my question is not the same as Extract associated value of enum case into a tuple
It's very simple, that answer access the values inside the if
statement, rather than as an Optional
like in my question. To specify a little more, imagine I have to extract values from multiple enums, and maybe enums inside enums, for that I'd need nested if
's, or guard
's, but with guard
I wouldn't be able to continue the flow, since it forces a return
.
Upvotes: 1
Views: 2040
Reputation: 181
Add two computed properties for success case and failure case respectively.
enum Result<S, F> {
case success(S)
case failure(F)
var successValue: S? {
switch self {
case .success(let value):
return value
case .failure:
return nil
}
}
var failureValue: F? {
switch self {
case .failure(let value):
return value
case .success:
return nil
}
}
}
let resultSuccess = Result<Int, String>.success(1)
let resultFailure = Result<Int, String>.failure("Error")
if let error = resultFailure.failureValue {
// do something
print(error)
}
Upvotes: 1
Reputation:
This technique from the question "Accessing an Enumeration association value in Swift" will do it:
enum Result<S, F> {
case success(S)
case failure(F)
}
let resultFailure = Result<Int, String>.failure("Error")
var error: String?
if case let Result.failure(value) = resultFailure {
error = value
}
print(error) // Optional("Error")
This will also work in place of the "if case let =" construct:
switch resultFailure {
case let Result.failure(value): error = value
default : error = nil
}
Here you go, 1 line and uses let
:
let error: String? = { if case let .failure(value) = resultFailure { return value }; return nil }()
Upvotes: 0
Reputation: 335
I'm afraid this is the most you can get:
let error: String?
if case .failure(let e) = resultFailure {error = e}
Upvotes: 0