我正在编写一个可以从
JSON中解析类型的ID的库.但是,我发现类似的规则有点令人困惑.
例:
class AccountId : NSString { } let json : AnyObject? = "user-1" // Returned by NSJSONSerialization.JSONObjectWithData let s = json as? NSString // Succeeds,s == Some("user-1") let a = json as? AccountId // Fails,a == nil
为什么第一个typecast成功,而第二个失败? NSString有没有什么神奇的东西,它不会交叉到Swift-class?
我正在使用XCode版本6.1(6A1030)(写作时的最新版本).
解决方法
作为一般规则,如果您有层次结构的类A – > B – > C(C继承自B,而A继承自A),并且你有一个B的实例,你可以上传到A,但是你不能down to C.
原因是C可能添加在B中不可用的属性,因此编译器或运行时将不知道如何初始化附加数据,更不要说它也必须分配.
请注意,多态使您可以使用变量进行upcast和downcast – 这意味着,如果您将C的实例存储在A类变量中,则可以将该变量转换为B和C,因为它实际上包含一个C.但是,如果变量包含B的实例,则可以向B进行倒转,但不能为C.
在你的情况下,而不是downcasting你应该专门的接受NSString的构造函数,但我怀疑在NSString的这种特殊情况下,它不能完成(没有NSString指定的初始化程序接受一个字符串作为参数).如果你能够做到这一点,你的代码将会如下所示:
var json: AnyObject? = "test" if let string = json as? NSString { let a = AccountId(string: string) }
在这一点上,您可以使用一个实例的AccountId或NSString的预期