ios - Swift 中的类型转换

标签 ios types casting 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

为什么第一个类型转换成功而第二个类型转换失败? NSString 有什么神奇之处,它不会交叉到 Swift-only 类吗?

我使用的是 XCode 版本 6.1 (6A1030)(撰写本文时最新版本)。

最佳答案

作为一般规则,如果您有类 A -> B -> C 的层次结构(C 继承自 B,而 B 又继承自 A),并且您有 B 的实例,则可以向上转型到 A,但你不能垂头丧气到 C。

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

请注意,多态性允许您使用变量进行向上转型和向下转型 - 这意味着,如果您将 C 的实例存储在 A 类型的变量中,则可以将该变量转换为 B 和 C,因为它实际上包含一个实例C 的。但是如果变量包含 B 的实例,则可以向下转换为 B,但不能向下转换为 C。

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

var json: AnyObject? = "test"
if let string = json as? NSString {
    let a = AccountId(string: string)
}

此时您可以使用 a,其中需要 AccountIdNSString 的实例

关于ios - Swift 中的类型转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26104487/

相关文章:

ios - 使用自定义 init 实例化带有标识符的 View Controller

c++ - 如何在 unsigned int 和 int 之间安全地进行 static_cast?

iphone - 野外的 NSOperationQueueDefaultMaxConcurrentOperationCount

ios - 我的 TableView 未填充我的自定义单元格

function - Haskell 错误 - 无法匹配预期类型

c++ - 从对象列表、模板、C++ 中获取参数的类型

C++ 多重继承 + 虚函数(- 歧义)= 奇怪的行为(也是函数指针)

实体和管理器抽象的 C++ 设计

ios - 我想根据服务器响应的文本更改我的标签颜色

c - 错误 : conflicting types for 'x'