在Swift中转换 [英] Typecasting in Swift

查看:110
本文介绍了在Swift中转换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在写一个库,可以解析来自JSON的类型化的Id。



例如:

  class AccountId:NSString {} 

let json:AnyObject? =user-1//由NSJSONSerialization.JSONObjectWithData返回
让s = json as? NSString // Succeeds,s == Some(user-1)
让a = json as? AccountId // Fails,a == nil

为什么第一个类型转换成功而第二个失败?有没有一些神奇的 NSString ,它不交叉到只Swift的类?



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

解决方案

作为一般规则, A - > B - > C(C继承自B,它继承自A),你有一个B的实例,你可以向A转换,但是你不能向下转换为C.



原因是C可能添加了在B中不可用的属性,所以编译器或运行时不知道如何初始化附加数据,更不用说它必须被分配。 / p>

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



在你的case,而不是downcasting你应该专门化一个构造函数接受 NSString ,但我怀疑在这个特定的情况下 NSString 它不能做(没有 NSString 指定的初始化程序接受一个字符串作为参数)。如果你能够这样做,那么你的代码看起来像:

  var json:AnyObject? =test
如果let string = json as? NSString {
let a = accountId(string:string)
}

此时可以使用 a ,其中 AccountId NSString 预期


I am writing a library which can parse typed Ids from JSON. However, I am finding the typecasting rules a little baffling.

Example:

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

Why does the first typecast succeed while the second one fail? Is there something magical about NSString which does not crossover to Swift-only classes?

I am using XCode Version 6.1 (6A1030) (the latest at the time of writing).

解决方案

As a general rule, if you have a hierarchy of classes A -> B -> C (C inherits from B, which in turn inherits from A), and you have an instance of B, you can upcast to A, but you cannot downcast to C.

The reason is that C might add properties which are not available in B, so the compiler or the runtime wouldn't know how to initialize the additional data, not to mention that it must also be allocated.

Note that polymorphism allows you do to upcast and downcast with variables - which means, if you have an instance of C stored in a variable of type A, you can cast that variable to B and C, because it actually contains an instance of C. But if the variable contains an instance of B, you can downcast to B, but not to C.

In your case, rather than downcasting you should specialize a constructor accepting NSString, but I suspect that in this specific case of NSString it cannot be done (there's no NSString designated initializer accepting a string as argument). If you are able to do that, then your code would look like:

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

and at that point you can use a where an instance of either AccountId or NSString is expected

这篇关于在Swift中转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆