简体   繁体   English

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

[英]What's the difference between “as?”, “as!”, and “as”?

Before I upgraded to Swift 1.2, I could write the following line: 在我升级到Swift 1.2之前,我可以编写以下行:

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

Now it forces me to write this line: 现在它迫使我写下这一行:

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

My question is, if I'm forced to write it as above, couldn't I just write the code below and it would do the same thing? 我的问题是,如果我被迫按上述方式编写,我不能只编写下面的代码,它会做同样的事情吗? Would it give me the same result in all values of imageDetails? 它会在imageDetails的所有值中给出相同的结果吗?

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

The as keyword used to do both upcasts and downcasts: as关键字用于执行upcast和downcast:

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

var object = aView as NSObject // upcast 

var specificView = aView as UITableView // downcast

The upcast, going from a derived class to a base class, can be checked at compile time and will never fail. 从派生类到基类的upcast可以在编译时检查,永远不会失败。

However, downcasts can fail since you can't always be sure about the specific class. 但是,由于您无法始终确定特定的类,因此向下转换可能会失败。 If you have a UIView, it's possible it's a UITableView or maybe a UIButton. 如果你有一个UIView,它可能是一个UITableView或UIButton。 If your downcast goes to the correct type – great! 如果你的堕落者去了正确的类型 - 太棒了! But if you happen to specify the wrong type, you'll get a runtime error and the app will crash. 但是,如果您碰巧指定了错误的类型,您将收到运行时错误,应用程序将崩溃。

In Swift 1.2, downcasts must be either optional with as? 在Swift 1.2中,downcast必须是可选的as? or “forced failable” with as!. 或者“强制可以”作为! If you're sure about the type, then you can force the cast with as! 如果你确定类型,那么你可以强制演员! similar to how you would use an implicitly-unwrapped optional: 类似于如何使用隐式解包的可选项:

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

var tableView = aView as! UITableView

The exclamation point makes it absolutely clear that you know what you're doing and that there's a chance things will go terribly wrong if you've accidentally mixed up your types! 感叹号清楚地表明你知道自己在做什么,而且如果你不小心混淆了你的类型,那么事情就会出现严重错误!

As always, as? 一如既往? with optional binding is the safest way to go: 使用可选绑定是最安全的方法:

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

Got this from a site: SOURCE 从一个网站得到这个: 来源

as

In Swift 1.2 and later, as can only be used for upcasting (or disambiguation) and pattern matching : 在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?

The conditional cast operator as? 条件转换运算符as? tries to perform a conversion, but returns nil if it can't. 尝试执行转换,但如果不能,则返回nil Thus its result is optional. 因此,其结果是可选的。

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

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

as!

The as! as! operator is for forced type conversion. 运算符用于强制类型转换。

Use the forced form of the type cast operator ( as! ) only when you are sure that the downcast will always succeed. 仅当您确定向下转换将始终成功时,才使用类型转换运算符的强制形式( as! )。 This form of the operator will trigger a runtime error if you try to downcast to an incorrect class type. 如果您尝试向下转换为不正确的类类型,则此形式的运算符将触发运行时错误

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

The correct idiom that should do exactly what you want (in all versions of Swift at least upto and including 1.2) is the as? 应该完全符合你想要的正确习惯用法(至少在所有版本的Swift中包括1.2)是as? optional cast. 可选演员。

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

The optional cast returns an optional (Int? in this case) and is tested at runtime. 可选的强制转换返回一个可选的(在这种情况下为Int?)并在运行时进行测试。 Your original code probably forced a cast to the optional type. 您的原始代码可能会强制转换为可选类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM