为什么不能在没有警告的情况下将Optional分配给`Any`类型的变量? [英] Why can't you assign an Optional to a variable of type `Any` without a warning?

查看:178
本文介绍了为什么不能在没有警告的情况下将Optional分配给`Any`类型的变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面的代码编译时没有警告:

The following code compiles without warning:

var anything: Any
anything = "woof"

可以理解... Any是任何类型,值类型或引用类型.

Makes sense... Any is any type, value type or reference type.

但是,如果我们创建诸如Double?之类的可选变量,则此代码将引发警告:

However, if we create an optional variable like a Double?, this code throws a warning:

var anything: Any
let aDouble: Double? = 3
anything =  aDouble

但是此代码不会引发警告:

But this code does not throw a warning:

enum AnEnum<T>: {
    case first
    case second (T)
}

var anEnum: AnEnum<String> = .first
anything = anEnum



您可以合理地认为版本2会引发警告,因为Any不是Optional类型,而Double?Optional类型.尝试将Optional分配给非可选类型是一种类型不匹配.



You can rationalize that version 2 throws a warning because Any is not an Optional type, and Double? is an Optional type. Trying to assign an Optional to a non-optional type is sort of a type mismatch.

但是,在幕后,Optional是带有.none大小写的enum和带有.some大小写的.some大小写具有关联值的enum.我的版本3使用了enumAnEnum,它也有2种情况,其中第二种具有关联的值. AnEnum类型几乎与Swift本机Optional类型相同.

However, under the covers, an Optional is an enum with a .none case, and with a .some case, where the .some case has an associated value. My version 3 uses an enum, AnEnum, that also has 2 cases, the second of which has an associated value. The AnEnum type is nearly identical to the Swift native Optional type.

为什么要为anything分配AnEnum值,但不能为anything分配可选值?

Why is assigning an AnEnum value to anything ok, but assigning an Optional value to anything is not ok?

(我开始回答这个问题:带有以下内容的快速字典混合类型(可选和非可选))

(I started to answer this question: Swift dictionary with mix types (optional and non-optional))

然后意识到我真的不知道答案.

And then realized that I didn't really know the answer.

推荐答案

很简单,这是因为Any就像蟑螂汽车旅馆(可选).

Quite simply, it's because Any is like a Roach Motel for Optionals.

罗奇汽车旅馆(Roach Motel)是一个蟑螂陷阱,其座右铭是:蟑螂会签入,但他们不会签出." Any和Optionals也是如此.您可以将可选"放入任意"中,但是再也无法获得它了.

The Roach Motel is a cockroach trap whose motto is, "Roaches check in, but they don't check out." The same is true for Any and Optionals. You can put an Optional into an Any, but you can never get it out again.

要了解我的意思,我们首先将 else 放入Any中,然后再次将其取出:

To see what I mean, let's first put something else into an Any and get it out again:

let s : String = "howdy"
let any : Any = s
let s2 = any as! String
s2 // "howdy"

现在让我们尝试使用Optional:

Now let's try that with an Optional:

let s : String? = "howdy"
let any : Any = s
let s2 = any as! String? // error

糟糕!您不能将非可选的"down"强制转换为可选,因此原始的可选会丢失.

Ooops! You can't cast a nonOptional "down" to an Optional, so the original Optional is lost.

包装的 不会丢失.您仍然可以打开它:

The thing wrapped by the Optional is not lost. You can still unwrap it:

let s : String? = "howdy"
let any : Any = s
let s2 = any as! String
s2 // "howdy"

但是现在s2是一个字符串,而不是一个可选的. Optional永远消失了.你不能把它弄出来.您无法确定Any 中是否包含可选内容.没了.

But now s2 is a String, not an Optional. The Optional is gone for good. You can't get it out. You can't find out that what was put into the Any was an Optional. It's gone.

所以这就是为什么将Optional放入Any时总是会发出警告的原因.编译器说:您可以执行此操作,但是您真的了解自己在做什么吗?"而且,如果这样做,可以通过以下方法使警告消失(错误消息会告诉您它们是什么).

So that's why putting an Optional into an Any always elicits a warning. The compiler is saying: "You can do this, but do you really understand what you're doing?" And if you do, there are ways to silence the warning (and the error message tells you what they are).

这篇关于为什么不能在没有警告的情况下将Optional分配给`Any`类型的变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆