在Swift中进行类型转换

mus*_*_ut 15 types casting ios swift

我正在编写一个可以从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
Run Code Online (Sandbox Code Playgroud)

为什么第一个类型转换成功而第二个类型失败?是否有一些神奇的东西NSString不会与Swift-only类交叉?

我正在使用XCode版本6.1(6A1030)(在撰写本文时的最新版本).

Ant*_*nio 22

作为一般规则,如果你有一个类的层次结构A - > B - > C(C继承自B,而继承自A),并且你有一个B的实例,你可以向上转换为A,但你不能向下倾斜到C.

原因是C可能会添加B中不可用的属性,因此编译器或运行时将不知道如何初始化其他数据,更不用说它也必须分配.

注意,polymorphism允许你使用变量进行upcast和downcast - 这意味着,如果你有一个存储在A类变量中的C实例,你可以将该变量强制转换为B和C,因为它实际上包含一个C的实例.但是如果变量包含B的实例,则可以向下转换为B,但不能向C转发.

在你的情况下,而不是向下转换你应该专门接受一个构造函数NSString,但我怀疑在这个特定的情况下NSString它不能完成(没有NSString指定的初始化程序接受字符串作为参数).如果您能够这样做,那么您的代码将如下所示:

var json: AnyObject? = "test"
if let string = json as? NSString {
    let a = AccountId(string: string)
}
Run Code Online (Sandbox Code Playgroud)

并且在那时你可以使用a任何一个AccountIdNSString预期的实例