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

在升级到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 

as关键字用来做upcast和downcasts:

 // Before Swift 1.2 var aView: UIView = someView() var object = aView as NSObject // upcast var specificView = aView as UITableView // downcast 

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

然而,沮丧可能会失败,因为你不能总是确定具体的类。 如果你有一个UIView,这可能是一个UITableView或UIButton。 如果你的沮丧去正确的types – 太棒了! 但是如果你碰巧指定了错误的types,你会得到一个运行时错误,应用程序将崩溃。

在Swift 1.2中,downcasts必须是可选的as? 或“强制failable”与! 如果你确定这个types,那么你可以用as来强制转换! 类似于你将如何使用隐式解开的可选项:

 // After Swift 1.2 var aView: UIView = someView() var tableView = aView as! UITableView 

感叹号清楚地表明,你知道你在做什么,如果你不小心混淆了你的types,那么事情就会变得非常糟糕!

一如既往? 与可选的绑定是最安全的方式去:

 // 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

as

Swift1.2和更高版本中,只能用于上传 (或消除歧义)和模式匹配

 // '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! 运算符是强制types转换。

只有当你确定 downcast将总是成功时,才使用types转换运算符的强制forms( as! )。 如果尝试向下转换为不正确的类types,则此运算符forms将触发运行时错误

 // '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 

正确的成语应该做什么你想要的(在所有版本的Swift中,至less包括1.2)是as? 可选投。

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

可选的转换返回一个可选的(在这种情况下是Int?),并在运行时进行testing。 您的原始代码可能会强制转换为可选types。