There may be several mistakes in this code, but the behavior seems incorrect. The obvious answer is to not do this, but I believe it may be uncovering a bug (or not, I have no idea 🙂).
In the following example playground we upcast a Dictionary to AnyObject and then perform a failing select which returns nil. The fact that we can do a subscript on an AnyObject is odd, but the compiler does not complain.
My real surprise is that the guard does not catch the nil assignment to y1. The following print shows y1 as nil and the if y1 == nil does catch the nil.
This is also odd because a "guard let foo =" does not (should not?) create an optional, so the following if y1 == nil should have been caught by the compiler? When I looked at the variable in the debugger, the type was "AnyObject?!" and the value was "nil". This might be a clue.
Finallly I downcast the AnyObject to Dictionary and it operates as expected.
import Foundation
var x = ["asdf":"qwer"]
var x1:AnyObject = x
guard let y1 = x1["1"] else {
print("This is the expected case, but does not happen")
exit(3)
}
print("Unexpected, the value is actually \(y1)")
if y1 == nil {
print("caught")
}
guard let y2 = (x1 as! Dictionary<String,String>)["1"] else {
print("This is the expected case")
exit(3)
}This is a weird corner case, and I would not bring this up unless I actually ran into this. It was in a program that was processing JSON. This playground is an attempt to isolate this into the smallest possible example.
Maybe this is just an FYI as I will change my code to do the downcast so that the guard works.
Since guards are the primary defense against invalid parameters, should this be a problem?
I am running Xcode Version 7.2 beta (7C62b)