> On Oct 9, 2016, at 1:10 PM, Erica Sadun via swift-evolution > <[email protected]> wrote: > > 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.)
This is a bug. 'String as NSString' works, and you can cast through Optionals 'T? as? U', so transitively this also works, despite the misleading warning. Please file a bug report if you haven't yet. -Joe
_______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
