“as?”,“as!”和“as”之间有什么区别?

时间:2015-04-14 21:47:56

标签: swift casting

在升级到Swift 1.2之前,我可以编写以下代码:

if let width = imageDetails["width"] as Int?

现在它迫使我写下这一行:

if let width = imageDetails["width"] as! Int?

我的问题是,如果我被迫按上述方式编写,我不能只编写下面的代码,它会做同样的事情吗?它会在imageDetails的所有值中给出相同的结果吗?

if let width = imageDetails["width"] as Int

3 个答案:

答案 0 :(得分:66)

用于进行向上转发和向下转发的as关键字:

// Before Swift 1.2
var aView: UIView = someView()

var object = aView as NSObject // upcast 

var specificView = aView as UITableView // downcast

从派生类到基类的upcast可以在编译时检查,永远不会失败。

但是,由于您无法始终确定特定的类,因此向下转换可能会失败。如果你有一个UIView,它可能是一个UITableView或UIButton。如果你的堕落者去了正确的类型 - 太棒了!但是,如果您碰巧指定了错误的类型,则会出现运行时错误,应用程序将崩溃。

在Swift 1.2中,向下转换必须是可选的as?或者“强制可以”作为!如果你确定类型,那么你可以强制演员!类似于如何使用隐式解包的可选项:

// After Swift 1.2
var aView: UIView = someView()

var tableView = aView as! UITableView

感叹号清楚地表明你知道自己在做什么,而且如果你不小心混淆了你的类型,那么事情就会出现严重错误!

一如既往?使用可选绑定是最安全的方法:

// This isn't new to Swift 1.2, but is still the safest way
var aView: UIView = someView()

if let tableView = aView as? UITableView {
  // do something with tableView
}

从网站获得此信息:SOURCE

答案 1 :(得分:40)

as

在Swift 1.2及更高版本中,as只能用于向上转换(或消除歧义)和模式匹配

// 'as' for disambiguation
let width = 42 as CGFloat
let block = { x in x+1 } as Double -> Double
let something = 3 as Any?  // optional wrapper can also be added with 'as'


// 'as' for pattern matching
switch item {
case let obj as MyObject:
    // this code will be executed if item is of type MyObject
case let other as SomethingElse:
    // this code will be executed if item is of type SomethingElse
...
}

as?

条件强制转换操作符as?尝试执行转换,但如果不能,则返回nil。因此,其结果是可选的。

let button = someView as? UIButton  // button's type is 'UIButton?'

if let label = (superview as? MyView)?.titleLabel {
    // ...
}

as!

as!运算符用于强制类型转换。

  

仅当您确定时,才会使用强制形式的类型转换运算符(as!),即向下转换将始终成功。如果您尝试向下转换为不正确的类类型,则此形式的运算符将触发运行时错误

// 'as!' for forced conversion.
// NOT RECOMMENDED.
let buttons = subviews as! [UIButton]  // will crash if not all subviews are UIButton
let label = subviews.first as! UILabel

答案 2 :(得分:0)

正确的习惯用法应该完全符合你的要求(至少在所有版本的Swift中包括1.2)是as?可选的演员。

if let width = imageDetails["width"] as? Int

可选的强制转换返回一个可选的(在本例中为Int?)并在运行时进行测试。您的原始代码可能会强制转换为可选类型。

相关问题