a preambula,
i created a helper function:
func cast<T>(_ value: Any?, to: T.Type) -> T? {
return value != nil ? (value as! T) : nil
}
to use it like this:
let dog = cast(any, to: Dog.self)
the idea is that it is a "stricter" version of the "as?" operator:
let dog = any as? Dog // will return nil when a car is passed, i want a crash here in this case.
let dog = any != nil ? (any as! Dog) // so i want this: if it is not nil it must be a dog (*)
let dog = cast(any, to: Dog.self) // a bit shorter and less visually disturbing
(* note that the extra parens around "(any as! Dog)" are there to stop a warning).
now the question, probably to swift designers, but anyone's input is welcome:
this cast function is not as nice as the built-in "as?" operator. i can not pass "Dog" alone in this context, I have to put it as "Dog.self". is there some deep logic why it is so? i believe in this context "Dog" alone can not mean anything else (useful), what harm it would make to treat "Dog" here as if "Dog.self" was passed?
The difference between Dog and Dog.self is that "Dog" is just the name of the type, but "Dog.self" is a reference to the metatype object that represents the type. As it happens, it's possible for the compiler to distinguish between places where the name is required, and places where a metatype object is required, and it's a planned future enhancement to Swift to allow them both to be written Dog — but it's likely not a small change internally.
For now, you could try using any as! Dog? to "safely" cast an unknown optional to an optional Dog. It perhaps doesn't do exactly the same thing as your "cast" function, but it should be close enough. (For example, the two techniques might produce different results for a value of type Dog?? — that's a double optional, which is an edge case you probably don't care about.)