I have two values, the expectation is that they are both the same type but the 2nd value could be of type Any? and I want to cast that value to the type of the first value. I tried the following but keep getting the error that type is not in scope
let type = type(of: value1)
var value2 = value2 as? type
Is there a way I can cast to a type that I've captured?
The right hand side of a type casting operator has to be a type name, so you can't use a metatype value in that position (this is also why you don't have to write casts as, e.g., as? String.self).
Could you expand on your example a bit? Even if you could cast in this way, it's not clear to me what useful work you could do with value2 once it has been cast to type. If you're just trying to figure out "are these two values of the same type?", you can compare their types directly with ==:
let areSameType = type(of: value1) == type(of: value2)
func cast<T, U>(_ t: T, to: U.Type) -> U? {
return t as? U
}
Usage:
if let x = cast(a, to: type(of: b)) {
// x is the same type as b
}
This works when the type of b is either concrete or a generic placeholder. If it is an existential you can try _openExistential, although that is not an official part of the language.
I don't think this has quire the right semantics for classes either. Consider:
class C {}
class A: C {}
class B: C {}
let a: Any? = A()
let b: C = B()
if let x = cast(a, to: type(of: b)) {
print("Same type")
}
print(type(of: a) == type(of: b))
Note that at the point where we're doing the == comparison, x is out of scope, so we can't really use it there. But we could add a print(type(of: x) == type(of: b)) into the if let block:
if let x = cast(a, to: type(of: b)) {
print("Same type")
print(type(of: x) == type(of: b))
}
The result is the same:
Same type
false
Anyway, since x and a always refer to the same value no matter how we initialize a (since cast(_:to:) passes the value straight through when the cast succeeds), AFAIK type(of: a) and type(of: x) should always be identical.