加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

swift – 为什么不能在没有警告的情况下为“Any”类型的变量分配

发布时间:2020-12-14 04:52:35 所属栏目:百科 来源:网络整理
导读:以下代码在没有警告的情况下编译: 版本1: var anything: Anyanything = "woof" 有道理……任何类型,值类型或引用类型. 但是,如果我们创建一个像Double?这样的可选变量,则此代码会抛出警告: 版本2: var anything: Anylet aDouble: Double? = 3anything =
以下代码在没有警告的情况下编译:

版本1:

var anything: Any
anything = "woof"

有道理……任何类型,值类型或引用类型.

但是,如果我们创建一个像Double?这样的可选变量,则此代码会抛出警告:

版本2:

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

但是这段代码没有发出警告:

版本3:

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

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

您可以合理化版本2抛出警告,因为Any不是Optional类型,而Double?是一个可选类型.尝试将Optional分配给非可选类型是一种类型不匹配.

但是,在封面下,Optional是带有.none大小写的枚举,并且带有.some大小写,其中.some大小写具有关联值.我的版本3使用枚举AnEnum,它也有2个案例,其中第二个具有相关值. AnEnum类型与Swift本机Optional类型几乎相同.

为什么将AnEnum值赋值给任何好的,但是为任何东西分配一个Optional值都不行?

(我开始回答这个问题:Swift dictionary with mix types (optional and non-optional))

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

解决方法

可选不仅仅是一个枚举.它也是每种类型的隐含促销.任何和可选的组合以奇怪的方式可能令人惊讶.例如,T?是的.牛逼?也是任意的. Any是Any,Any?是的.任何??也是任意的.

这会产生一些令人头疼的问题,而细微的上传和下线让人们很难清楚Any的选择性究竟是什么.例如.

var anything: Any = ""
let aDouble: Double? = 3
anything = aDouble as Any
let x = anything as? Double

这是什么?好吧,aDouble是可选的< Double>,而不是Double,所以? Double应返回nil.但它并不是因为魔术.它返回Optional(3).坦率地说这很奇怪(尝试用一个版本的MyOptional作为枚举来获得相同的东西),但另一方面它会非常糟糕.考虑:

let data: [String: Any] = ["aDouble": aDouble]
let y = data["aDouble"] as? Double

你是双?在这里,不是双??因为可选的合并.谢天谢地.但这很奇怪.如果你的泛型涉及基于Optional的一致性,这可能会让人感到困惑(而且确实如此;有很多问题出现在那里……)现在用Any替换上面的Double,它真的很快就开始了.

所以编译器警告你将Any与Optional混合是一个坏主意,并且可能导致奇怪的类型结果,并且你肯定应该在任何时候调用它. (也许你应该停止使用Any,因为它几乎不是你真正的意思.)

为了使它成为我能想到的最具体的例子,请考虑:

var anything: Any = ""
let one: Int = 1
let maybeTwo: Int? = 2

anything = one
anything as? Int // fine

anything = maybeTwo
anything as? Int? // illegal (see below)
anything as? Int  // fine (but why? that's not what we put in.)

你会认为这是平行的,但事实并非如此.当你将Optionals投入混音时,你不能只提出你输入的类型.

顺便说一句,有趣的附录,你不能从Any转换为可选类型.

let x = anything as? Double? // Illegal

这真的很有趣,因为任何东西都是Double?:

(lldb) p anything
(Any) $R4 = {
  payload_data_0 = 0x4008000000000000
  payload_data_1 = 0x0000000000000000
  payload_data_2 = 0x0000000000000000
  instance_type = Double?
}

那么我怎么能区分“任何东西是双重的?但是没有”与“任何东西是字符串”之间的区别?你认为你可以测试一下,但我认为你不能,因为这一切都不能持续.相反,它试图方便.但是你不能太用力或者所有接缝都会显示出来.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读