Xcode 12.5 beta 3, Swift 5.3 无法检查 Any 的 nil 值

时间:2021-03-12 16:34:46

标签: swift xcode

我有以下测试在过去几年发布的所有 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?

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

更新 想要更加困惑吗?

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 在放入字典时发生了问题。

1 个答案:

答案 0 :(得分:1)

感谢 Jessy 指出 Optional<Any> 内部实际上可能有 some 值并且可能是 nil。我想出了一个检查 Any 是否为 nil 的函数,它可以在旧的和最新的 Xcode 中工作(在 12.5 beta 3 中肯定已经改变了一些打破旧测试的东西,即将 nil 转换为 Any 到字典值导致要包装到 Optional<Any>.some 中而不是将其视为 Optional<Any>.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)