我在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
是否为零的最佳方式是什么?
让我详细说明一下,
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)
}
答案 0 :(得分:10)
使用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
:
您也可以将模式测试与switch
一起使用:
var b: Bool?
var a = b as Any
switch a {
case Optional<Any>.none:
print("nil")
default:
print("not nil")
}
nil
答案 1 :(得分:0)
我发现Mirror.Child非常奇怪,标签可以为空,但是 值似乎不能为空。
当label
为nil
时,您可能在数组内,其中的标签不存在。
我不知道如何检查该值是否为零。
要检查Any
是否为Optional
,您可以实施以下方法:
extension Optional {
static func isNil(_ object: Wrapped) -> Bool {
switch object as Any {
case Optional<Any>.none:
return true
default:
return false
}
}
}
示例用法:
let a: Bool? = nil
let b: Bool? = true
print(Optional.isNil(a)) // prints 'true'
print(Optional.isNil(b)) // prints 'false'
上述代码的更详细示例如下:
enum ContentType {
case value // single value object
case array // object is an array
case object // object is a structure
}
func getType(from mirror: Mirror) -> ContentType {
// if there are no children, we are probably a single value
if mirror.children.count == 0 {
return .value
}
if mirror.children.first?.label == nil {
// its probably an array
return .array
}
// everything else is an object (dictionary)
return .object
}
func formArray(from mirror: Mirror) -> [(index: Int, value: Any)] {
var startIndex = mirror.children.startIndex
var array: [(index: Int, value: Any)] = []
for index in 0..<mirror.children.count {
let child = mirror.children[startIndex]
startIndex = mirror.children.index(after: startIndex)
array.append((index: index, value: child.value))
}
return array
}
func formObjects(from mirror: Mirror) -> [(label: String, value: Any)] {
let objects: [(label: String, value: Any)] =
mirror.children.map { (label: $0.label ?? "", value: $0.value) }
return objects
}
func checkObject(_ object: Any) {
let mirror = Mirror(reflecting: object) // object can be any object.
let objectType = getType(from: mirror)
switch objectType {
case .value:
print("value: \(object)")
case .array:
let array = formArray(from: mirror)
for element in array {
let isNil = Optional.isNil(element.value)
print("Index \(element.index) is \(element.value), the value \(isNil ? "is" : "is not") nil.")
}
case .object:
let objects = formObjects(from: mirror)
for element in objects {
let isNil = Optional.isNil(element.value)
print("\(element.label) is \(element.value), the value \(isNil ? "is" : "is not") nil.")
}
}
}
struct Test {
let text: String?
let number: Int
}
let object = Test(text: nil, number: 42)
checkObject(object)
//text is nil, the value is nil.
//number is 42, the value is not nil.
let array = [1, 2, 3]
checkObject(array)
//Index 0 is 1, the value is not nil.
//Index 1 is 2, the value is not nil.
//Index 2 is 3, the value is not nil.
let arrayWithOptionals = [1, nil, 3]
checkObject(arrayWithOptionals)
//Index 0 is Optional(1), the value is not nil.
//Index 1 is nil, the value is nil.
//Index 2 is Optional(3), the value is not nil.
这应该可以解决您的问题。