如何在Swift中检查`Any(不是Any?)`是否为nil

23

我正在使用Swift中的Mirror,我发现Mirror.Child非常奇怪,标签是可空的,但值似乎不可空。

public typealias Child = (label: String?, value: Any)

我不知道如何检查该值是否为空。

let b: Bool? = true
let a: Any = b
print(a == nil) // false

我有一个解决方案:

print(String(describing: a) == "nil") // true

但这显然不是一个好的解决方案。

检查 a 是否为 nil 的最佳方法是什么?

让我提供更多细节:

let mirror = Mirror(reflecting: object) // object can be any object.
for child in mirror.children {
    guard let label = child.label else {
        continue
    }
    // how to check if the value is nil or not here ?
    setValue(child.value, forKey: label)
}

1
我尚未找到Mirror是您想要的工具的情况。如果您试图创建反射系统,您会发现Mirror无法解决这个问题。目前在Swift中无法建立反射系统(这就是为什么Codable必须具有特殊的编译器支持;不能在Swift中编写它)。 - Rob Napier
1
我对你使用 setValue(_:forKey:) 也感到困惑。这是 ObjC 运行时的一部分,除非你有自己的版本。Mirror 和 ObjC 运行时并不特别兼容。如果你只想反射 NSObject 的子类,那么 ObjC 运行时有广泛的支持。 - Rob Napier
1
你不需要使用“Mirror”,而是要深入了解ObjC运行时。例如,使用class_getPropertyclass_getInstanceMethod等方法。 - Rob Napier
1
实际上,我撤回之前的说法。如果这是NSManagedObject,那就比那更容易了。看一下NSManagedObjectModel和特别是NSEntityDescription。Core Data会告诉你关于托管对象的大部分信息。 - Rob Napier
1
@RobNapier 我明白了,setValue(child.value, forKey: label) 是用于 NSManagedObject 的,而 Mirror(reflecting: object) 中的 object 则是一个 Swift 对象。 - JIE WANG
显示剩余9条评论
1个回答

40

使用 if case

您可以使用 if case Optional<Any>.none = a 来测试 a 是否为 nil

var b: Bool?
var a = b as Any
if case Optional<Any>.none = a {
    print("nil")
} else {
    print("not nil")
}
nil
b = true
a = b as Any
if case Optional<Any>.none = a {
    print("nil")
} else {
    print("not nil")
}
not nil
您也可以在使用 switch 时使用模式测试:
var b: Bool?
var a = b as Any

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

2
很好的回答,但是使用switchif case更清晰。 - Ashley Mills
3
谢谢@AshleyMills。我在答案中添加了 switch - vacawama
由于Optional是一个enum,我认为值得指出的是你也可以像这样做相反的case,例如guard case Optional<Any>.some = b else { return } - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接