I've seen this question come up a few times, but haven't seen any nice short solutions. The problem is that I've got a function which returns an optional value of a base type, and I want to safe cast it to a derived type. But the optional itself might be nil, or the cast might fail; I don't care about knowing why it failed if it does.
In C++, dynamic_cast<> handles both of these: if you dynamic cast a NULL it fails, if you get the type wrong it fails. But in swift, I can't see anyway of doing it other than doing a double let, which is annoyingly unwieldy. (Or repeating the function call itself which is a non-starter for performance reasons.)
let dd = [String:AnyObject]()
if let v1 = dd["foobar"],
let v2 = v1! as? WantedType {
// v2 is of type WantedType
}
Too much. Surely we can get this down to one line? I'm sure I've reinvented a wheel, but here goes anyway:
struct GuardedAs<U> {
var result:U?
init<T>(_ v: T?) { result = (v == nil ) ? nil : (v! as? U) }
}
Now I can guard and cast at the same time:
if let v2 = GuardedAs<WantedType>(dd["foobar"]).result {
// do stuff with v2
}
Anybody got anything better? Is there a way I can make this an extension directly in the Optional class itself? I'm really hating the lack of syntax for calling a generic function simply like myFunction<U>() when myFunction takes no arguments. So I have to fake it with a structure.
In most other respects, this is a lovely language to work with. C++ metaprogramming tied me in knots. Constraints on types for generics rock.
You might have some better examples, but the double-let example needs to be fixed as:
if let v1 = dd["foobar"],
let v2 = v1 as? WantedType {
// v2 is of type WantedType
}(You have no need to put `!` after `v1` in the second `let`.)
And the more important thing is this example can be rewritten into single if-let:
if let v2 = dd["foobar"] as? WantedType {
// v2 is of type WantedType
}Not much worse than dynamic_cast, I think.