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

时间:2023-01-22 20:12:32

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

3 个解决方案

#1


55  

The as keyword used to do both upcasts and downcasts:

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

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

但是,downcast可能会失败,因为您不能总是确定特定的类。如果你有一个UIView,它可能是UITableView或者UIButton。如果你的downcast进入正确的类型-太好了!但是如果你指定了错误的类型,你会得到一个运行时错误,应用程序会崩溃。

In Swift 1.2, downcasts must be either optional with 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:

在Swift 1.2中,downcast必须是可选的吗?或者“*失败”与as!如果您确定类型,那么您可以使用as强制转换!类似于你如何使用一个隐含的未包装的可选选项:

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

这是从一个网站:来源

#2


36  

as

In Swift 1.2 and later, as can only be used for upcasting (or disambiguation) and pattern matching:

在Swift 1.2和之后,as只能用于upcasting(或消除歧义)和模式匹配:

// '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? tries to perform a conversion, but returns nil if it can't. Thus its result is optional.

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

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

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

as!

The 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. This form of the operator will trigger a runtime error if you try to downcast to an incorrect class type.

只有当您确信下行类型转换将始终成功时,才使用强制类型转换操作符(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

#3


0  

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? optional cast.

正确的习语应该做你想做的事情(在所有版本的Swift中,至少包括1.2)是a吗?可选的演员。

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

The optional cast returns an optional (Int? in this case) and is tested at runtime. Your original code probably forced a cast to the optional type.

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

#1


55  

The as keyword used to do both upcasts and downcasts:

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

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

但是,downcast可能会失败,因为您不能总是确定特定的类。如果你有一个UIView,它可能是UITableView或者UIButton。如果你的downcast进入正确的类型-太好了!但是如果你指定了错误的类型,你会得到一个运行时错误,应用程序会崩溃。

In Swift 1.2, downcasts must be either optional with 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:

在Swift 1.2中,downcast必须是可选的吗?或者“*失败”与as!如果您确定类型,那么您可以使用as强制转换!类似于你如何使用一个隐含的未包装的可选选项:

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

这是从一个网站:来源

#2


36  

as

In Swift 1.2 and later, as can only be used for upcasting (or disambiguation) and pattern matching:

在Swift 1.2和之后,as只能用于upcasting(或消除歧义)和模式匹配:

// '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? tries to perform a conversion, but returns nil if it can't. Thus its result is optional.

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

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

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

as!

The 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. This form of the operator will trigger a runtime error if you try to downcast to an incorrect class type.

只有当您确信下行类型转换将始终成功时,才使用强制类型转换操作符(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

#3


0  

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? optional cast.

正确的习语应该做你想做的事情(在所有版本的Swift中,至少包括1.2)是a吗?可选的演员。

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

The optional cast returns an optional (Int? in this case) and is tested at runtime. Your original code probably forced a cast to the optional type.

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