【问题标题】:Xcode 12.5 beta 3, Swift 5.3 fails to check Any for nil valueXcode 12.5 beta 3、Swift 5.3 无法检查 Any 的 nil 值
【发布时间】:2021-06-10 16:44:27
【问题描述】:

我在过去几年发布的所有 Xcode 版本中成功进行了以下测试Xcode 12.5 beta 3 除外

var nilString: String? = nil
var dict: [String: Any] = ["hello": nilString as Any]
var element = dict["hello"] as Any
print(element)
print(type(of: element))

switch element {
    case Optional<Any>.none:
        print("element is nil")
    default:
        assertionFailure("element is not nil. wtf?")
}

在 Xcode 12.4 中,我打印了这个

Optional(nil)
Optional<Any>
element is nil

在 Xcode 12.5 beta 3 中,我打印了这个

Optional(nil)
Optional<Any>
Fatal error: element is not nil. wtf?

有人能解释一下这个问题吗?我现在如何检查任何为零?它会在候选版本中修复吗?

更新 想要更加困惑?

var nilString: String? = nil
var element: Any = nilString as Any
print(element)
print(type(of: element.self))

switch element {
    case Optional<Any>.none:
        print("element is nil")
    default:
        assertionFailure("element is not nil")
}

输出:

nil
Optional<String>
element is nil

我想我的 nilString 在被放入字典时发生了问题。

【问题讨论】:

  • 一个可选的Dictionary 值破坏了当值设置为nil 时删除键的规则。在 Objective-C 中 NSDictionary nil 无论如何都不允许使用值。
  • 我不知道发生了什么变化,但印刷措辞不准确。 nil as String? / Optional&lt;String&gt;.noneAny 没有的地方工作。 IE。你可以找到nil,但你必须知道它的类型。
  • @Jessy 不过,print(type(of: element)) 给了我Optional&lt;Any&gt;
  • @Jessy 我想我做到了。让我仔细检查一下……
  • @Jessy 请检查我的答案,我仍然可能会错过一些东西

标签: swift xcode


【解决方案1】:

感谢Jessy 指出Optional&lt;Any&gt; 内部可能实际上有some 值并且可能是nil。我想出了一个检查 Any 是否为 nil 的函数,它适用于旧的和最新的 Xcode(在 12.5 beta 3 中肯定已经改变了一些已经打破旧测试的东西,即将转换为 Any 的 nil 放入字典值导致要包装到 Optional&lt;Any&gt;.some 中的值,而不是将其视为 Optional&lt;Any&gt;.none):

func isOptional(_ instance: Any) -> Bool {
    let mirror = Mirror(reflecting: instance)
    let style = mirror.displayStyle
    return style == .optional
}

func checkIfAnyIsNil(_ v: Any) -> Bool {
    if (isOptional(v)) {
        switch v {
        case Optional<Any>.none:
            return true
        case Optional<Any>.some(let v):
            return checkIfAnyIsNil(v)
        default:
            return false
        }
    } else {
        return false
    }
}

断言:

var nilString: String? = nil
var dict: [String: Any] = ["nilString": nilString as Any]

assert(checkIfAnyIsNil(dict["nilString"] as Any))
assert(checkIfAnyIsNil(nilString as Any))
assert(checkIfAnyIsNil("some string" as Any) == false)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多