I fiddled with generics in Swift and clicked on something that I can’t understand: if I pass the value to the type of the general parameter, then the cast does not work. If I try the same with static types, it works.
class SomeClass<T> { init?() { if let _ = 4 as? T { println("should work") } else { return nil } } } if let _ = SomeClass<Int?>() { println("not called") } if let _ = 4 as? Int? { println("works") }
Can anyone explain this behavior? Shouldn't both be equivalent?
Update
The above example is simplified to max. The following example illustrates the need for casting a little better.
class SomeClass<T> { init?(v: [String: AnyObject]) { if let _ = v["k"] as? T? { print("should work") } else { print("does not") return nil } } } if let _ = SomeClass<Int?>(v: ["k": 4]) { print("not called") } if let _ = SomeClass<Int>(v: ["k": 4]) { print("called") }
Second update
After @matt made me learn about AnyObject and Any , and @Darko pointed out in his comments how dictionaries make my example too complicated, here is my next refinement
class SomeClass<T> { private var value: T! init?<U>(param: U) { if let casted = param as? T { value = casted } else { return nil } } } if let _ = SomeClass<Int?>(param: Int(4)) { println("not called") } if let _ = SomeClass<Int>(param: Int(4)) { println("called") } if let _ = Int(4) as? Int? { println("works") } if let _ = (Int(4) as Any) as? Int? { println("Cannot downcast from Any to a more optional type 'Int?'") }
I tried to use init?(param: Any) before, but this gives the same problem as in the previous if , which is discussed elsewhere .
So it all boils down to: Has anyone really been far from ever casting something to a universal optional type? Anyway? I am happy to accept any working example.
source share