On 18 Sep 2014, at 3:55 am, Jens Alfke < email@hidden> wrote:
On Sep 17, 2014, at 10:34 AM, Marco S Hyman < email@hidden> wrote:
Get rid of the ? after dict["foo"]. It is not necessary. Yes, the return value is an optional. That's fine.
Yeah, I get that; but my assumption was that the "as? String" _expression_ represented a dereference of the value, so I'd need to unwrap it before that evaluated. It sounds like what really happens is that the "as?" operator knows about optionals and will evaluate to nil if the LHS is nil.
The message still seems wrong, though: the operand of the "?" is the dict lookup, which _is_ optional.
now generates the error 'String' is not a subtype of '(NSObject, AnyObject)' which goes to show that String and NSString aren't as equivalent as one would hope.
Yeah, so my interpretation is that this is a bug in either the compiler or the class library. The docs say String and NSString are equivalent. And the fact that the error message involves some hidden(?) intermediate type makes this seem unintentional. I'll file a bug report.
—Jens
I’ve fallen over this one a number of times now. Well actually there’s two things here.
The original ? before the ‘as?’ was wrong, ‘as?’ takes an optional and passes optionality on if necessary. So removing that to get
dict[“foo”] as? String
should work. However you now fall over the type inference engine in a way I’ve never been able to fully understand. There are two versions of the subscript operator for a dictionary of type Dictionary<K,V>, one takes a ‘K’ and returns a ‘V?’, which is what you’d expect, the other takes a DictionaryIndex<K,V> and returns a (K,V) tuple. I believe this is so you can enumerate dictionaries.
As far as I can tell, the compiler decides it’s going to use the DictionaryIndex<> overload, even though, again as far as I can tell, there’s no way to convert “foo” to a DictionaryIndex<NSObject,AnyObject> in the first place. However then that would make the return value a (NSObject,AnyObject) tuple and the error message it gets to first tells you you can’t convert it that a String. That’s where the strange error message comes from, the wrong subscript operator being attempted.
These two things work, I have been using the latter and stronger-typing any Dictionaries I bridge over from ObjC. In fact I usually do it right at the start in the original variable assignment
let val3 = dict[ “foo” ] as? NSString as? String let val4 = ( dict as [ NSObject:String ] )[ “foo” ]
|