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

Ale*_*lex 52 casting swift

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

if let width = imageDetails["width"] as Int?
Run Code Online (Sandbox Code Playgroud)

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

if let width = imageDetails["width"] as! Int?
Run Code Online (Sandbox Code Playgroud)

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

if let width = imageDetails["width"] as Int
Run Code Online (Sandbox Code Playgroud)

Een*_*dje 66

as关键字用于执行upcast和downcast:

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

var object = aView as NSObject // upcast 

var specificView = aView as UITableView // downcast
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

var tableView = aView as! UITableView
Run Code Online (Sandbox Code Playgroud)

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

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

// 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
}
Run Code Online (Sandbox Code Playgroud)

从一个网站得到这个:来源


jtb*_*des 41

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'
Run Code Online (Sandbox Code Playgroud)


// '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
...
}
Run Code Online (Sandbox Code Playgroud)

as?

有条件的类型转换操作符as?会尝试进行转换,但返回nil如果它不能.因此,其结果是可选的.

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

if let label = (superview as? MyView)?.titleLabel {
    // ...
}
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

  • 谢谢@jtbandes。这个答案比公认的答案更好。 (3认同)