Swift中如何判断Any类型值是否为nil(含Mirror场景)
Any value (from Mirror.Child) is nil Great question—this is a super common gotcha when working with Mirror and boxed Optional values in Swift. Let’s break down why your initial approach falls short, then walk through the reliable, idiomatic solutions.
Why a == nil doesn’t work
When you assign an Optional (like Bool?) to an Any variable, you’re not storing the underlying value directly—you’re storing the Optional instance itself. So if b is nil, let a: Any = b doesn’t make a equal to nil; it makes a hold an instance of Optional<Bool> that’s in the .none case. Comparing a == nil checks if the Any value itself is nil, which it never is here.
The robust way to detect nil
The best approach leverages Swift’s type system or Mirror to check if the Any value is an empty Optional. Here are two solid methods:
Method 1: Inspect with Mirror
We can check if the value’s mirror has an .optional display style and no children (since a nil optional has no associated value):
func isNil(_ value: Any) -> Bool { let mirror = Mirror(reflecting: value) return mirror.displayStyle == .optional && mirror.children.isEmpty }
Method 2: Pattern matching with Optional
Use Swift’s pattern matching to directly check if the value is an empty optional:
func isNil(_ value: Any) -> Bool { if case Optional<Any>.none = value { return true } return false } // Or a concise switch version: func isNil(_ value: Any) -> Bool { switch value { case Optional<Any>.none: return true default: return false } }
Apply this to your Mirror loop
Here’s how to integrate this into your code when iterating over mirror.children:
let mirror = Mirror(reflecting: object) for child in mirror.children { guard let label = child.label else { continue } let value = child.value if isNil(value) { // Handle nil case: set nil for the key setValue(nil, forKey: label) } else { // Extract the unwrapped value if needed (via Mirror) let unwrappedValue = Mirror(reflecting: value).children.first?.value ?? value setValue(unwrappedValue, forKey: label) } }
Why your string-based approach is risky
Using String(describing: a) == "nil" is fragile for two big reasons:
- Swift’s string representation of
nilcould change in future versions, breaking your code. - A custom type could override
descriptionto return "nil", leading to false positives.
Always rely on type checks or Mirror for this kind of logic—it’s far more reliable.
内容的提问来源于stack exchange,提问作者JIE WANG

