gpt4 book ai didi

ios - swift nil 任何!= nil

转载 作者:行者123 更新时间:2023-12-01 17:35:32 30 4
gpt4 key购买 nike

swift 5.1 。
考虑以下。

let x: Any? = nil
let y: Any = x
print("x \(x)") // x nil
print("type(of: x) \(type(of: x))") // type(of: x) Optional<Any>
print("x == nil \(x == nil)") // x == nil true
print("y \(y)") // y nil
print("type(of: y) \(type(of: y))") // type(of: y) Optional<Any>
print("y == nil \(y == nil)") // y == nil false

我们有两个变量,设置为相同的东西 - nil。
它们打印相同,它们的类型打印相同 - 但一个 == nil而另一个没有。
  • 为什么?
  • 鉴于这样的 Any ,人们怎么会发现它实际上是 nil 呢?
  • 最佳答案

    想想AnyOptional<Wrapped>像盒子。

  • Any是一个可以容纳任何东西的不透明盒子。你可以通过尝试使用 as? 来转换里面的东西来闪烁它。 .
  • Optional<Wrapped>是一个透明的盒子。它让您看到它的内容是 Optional<Wrapped>.some(wrapped) 的值。或 Optional<Wrapped>.none() .

  • 一个 Optional<Any>Any包含 Optional<Wrapped>不是一回事。

    1. x
    Optional<Any>.none 的值,又名 nil . nil被打印出来,所以这是有道理的。

    2. type(of: x)
    x 的类型, Optional<Any> ,正如我们所料。

    3. x == nil
    正在调用 == (T, T) -> Bool 类型的运算符.因为两个 args 需要是相同的类型,并且因为 x值为 Optional<Any>.none (类型为 Optional<Any> ), nil推断为 Optional<Any>.none .两者是等价的,所以我们得到 true ,正如预期的那样。

    4. y
    Any 类型的值.在编译时,关于 y 的信息一无所知。 .恰巧隐藏在 Any的不透明幕布背后的值(value)是 x . print实现“透视” Any instances ,向您展示真正存在的东西。

    5. type(of: y)
    正在做类似于 print 的事情.它使用运行时类型信息来准确查看存储在 y 中的运行时值。是。 y 的静态类型是 Any , 但是 type(of: y)告诉我们它的值的运行时类型是 Optional<Any> .

    6. y == nil
    这是它变得有点棘手的地方。

    根据静态已知的操作数类型,在编译时选择要调用的函数或运算符的重载。也就是说,运算符和函数不是根据参数的类型动态分派(dispatch)的,而是根据对象类型动态分派(dispatch)的方式(例如 foo 中的 foo.bar() )。

    此处选择的重载是 ==(lhs: Wrapped?, rhs: _OptionalNilComparisonType) -> Bool .你可以在 lines 449-481 of Optional.swift 上看到它的实现。 .

    它的左侧操作数是 Wrapped? ,又名 Optional<Wrapped> .

    它的右侧操作数是 _OptionalNilComparisonType .这是符合 ExpressibleByNilLiteral 的特殊类型.

    可选是一种符合 ExpressibleByNilLiteral 的类型, 表示你可以写 let x: Optional<Int> = nil ,并且编译器可以使用该协议(protocol)来理解 nil应该是 Optional<Int>.none . ExpressibleByNilLiteral协议(protocol)的存在是为了允许这种行为可以被其他类型扩展。例如,您可以想象一个 Python 互操作性框架,您希望能够在其中说出 let none: PyObject = nil , 可以传入 Python并解析为 None , Python 的空类型。

    这里发生的情况是左侧( y ,类型为 Any )被提升为类型 Any? .提升值的类型为 Optional<Any>.some(old_value_of_y) .右手边, nil , 用于实例化 _OptionalNilComparisonType 的值, 相当于调用 _OptionalNilComparisonType.init(nilLiteral: ()) .

    因此,您的调用站点相当于:
    Optional<Any>.some((Optional<Any>.none) as Any) == _OptionalNilComparisonType(nilLiteral: ()) /*
    ↑ ↑↖︎_the value of x_↗︎ ↑↑
    ↑ ↖︎_the value of y _________↗︎↑
    ↖︎_the value of y after promotion to optional__↗︎ */

    根据实现,左边是 some , 右边是 nil ,因此它们是不平等的。

    你可能会说:

    Well this is pretty non-obvious behaviour, it's not what I wanted.



    我会回应:

    Don't ignore the compiler errors, they're right on point:

    warning: comparing non-optional value of type Any to nil always returns false

    关于ios - swift nil 任何!= nil,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61530205/

    30 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com