Normally in guard and if condition lists, you look up a value in a dictionary
and conditionally cast:
if let value = dict[key] as? T, ...
The "as?" operator passes the Any? type through, and the lhs result is T, not
T?.
* dict[key] returns Any?
* Any? as T returns T?, not T??
* the conditional binding binds T? to T
* PROFIT!
However, this (somewhat illogical) "sugar" doesn't happen when you
conditionally cast T? to U, for example, when a dictionary is [AnyHashable:
String]:
guard let value = dict["Key"] as? NSString
else { fatalError() }
(see http://i.imgur.com/SkXkk6o.jpg <http://i.imgur.com/SkXkk6o.jpg>)
* dict[key] returns String?
* String? as T is guaranteed to fail
In this case, the compiler asserts that a cast from String? to an unrelated
type NSString always fails. You can mitigate this by sticking an "Any" cast in
the middle:
guard let value = dict["Key"] as Any as? NSString
else { fatalError() }
If that's not "magic", I don't know what is. (You can also cast the dictionary
to [AnyHashable: NSString], etc.)
Jack L's initial response: "oh, that's a weird bridging edge case 😕 it seems
like we should just make that work..."
http://twitter.com/_jackhl/status/784998768898744320
<http://twitter.com/_jackhl/status/784998768898744320>) but he asked me to
follow up here on SwiftEv. It seems to me that in conditional binding with
conditional casting, you're asking the compiler to do not one but *two* magical
things:
1. Apply what *looks* like assignment (I have a similar issue with if
case/guard case) but is actually something else
2. Apply what *looks* like conditional casting but which magically passes Any?
through to T?, not T??
I handwave this (but just the moment) and say "it's not really an assignment,
so it's not really a conditional cast". Jack asked me to bring this discussion
over to Swift Evolution and ask the greater community whether Swift is doing
these things right, and if not, how it should fix them.
Where I stand:
* If there's going to be magic, it should be documented (and it is not) in the
Swift Programming Language
* If there's going to be magic, it should work for T?, not just Any?
* I'd rather there not be magic here
-- E
p.s. I'd also rather that if-case/guard-case would use ":" like in switch
statements not "=", but no one seems to be responding to that thread, dagnabit_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution