Another way to do this is to write a function that takes all your cast functions as an argument. It returns the first that was successful or zero.
func first<T>(_ values: (() throws -> T)...) -> T? { return values.lazy.flatMap({ (throwingFunc) -> T? in return try? throwingFunc() }).first }
lazy ensures that values ββwill only be called until it finds the first match. By doing this this way, you can also add a lot of things very quickly.
You can use a function like this
return first(firstThing, secondThing, thirdThing) ?? "Default"
I also included the code that I used to test on the playground:
enum ThingError: Error { case zero } func firstThing() throws -> String { print("0") throw ThingError.zero return "0" } func secondThing() throws -> String { print("1") return "1" } func thirdThing() throws -> String { print("2") return "B" } func first<T>(_ values: (() throws -> T)...) -> T? { return values.lazy.flatMap({ (throwingFunc) -> T? in return try? throwingFunc() }).first } func tryThings() -> String { return first(firstThing, secondThing, thirdThing) ?? "Default" } tryThings()
source share