如何将Any中的Any值转换为Any?

时间:2016-12-02 02:03:05

标签: swift reflection

我正在使用反射来尝试检查结构是否具有nil值。

com.baz

如何将Any类型转换为Any?

4 个答案:

答案 0 :(得分:7)

要简单检查包含在nil中的属性值中的Any内容,可以,与其他答案中描述的方法相反,实际上可以解决方法通过直接将模式匹配应用于AnyOptional<Any>.none来投射/绑定/检查具体的非Optional<Any>.some(...)类型。

示例设置(不同的成员类型:我们不想仅仅为nil内容的反射检查注释所有这些不同的类型)

struct MyStruct {
    let myString: String?
    let myInt: Int?
    let myDouble: Double?
    // ...
    init(_ myString: String?, _ myInt: Int?, _ myDouble: Double?) {
        self.myString = myString
        self.myInt = myInt
        self.myDouble = myDouble
    }
}

简单记录:提取nil值属性的属性名称

Optional<Any>.none匹配的模式,如果您只想记录nil个有价值实体的信息:

for case (let label as String, Optional<Any>.none) in 
    Mirror(reflecting: MyStruct("foo", nil, 4.2)).children {
    print("property \(label) is nil")
}
/* property myInt is nil */

稍微更详细的日志记录:适用于nil以及非nil重要属性

Optional<Any>.some(...)匹配的模式,以防您需要更详细的日志记录(下面的绑定x值对应于您保证的非nil Any实例)

for property in Mirror(reflecting: MyStruct("foo", nil, 4.2)).children {
    if let label = property.label {
        if case Optional<Any>.some(let x) = property.value {
            print("property \(label) is not nil (value: \(x))")
        }
        else {
            print("property \(label) is nil")
        }
    }
}
/* property myString is not nil (value: foo)
   property myInt is nil
   property myDouble is not nil (value: 4.2) */

或者,后者使用switch案例代替:

for property in Mirror(reflecting: MyStruct("foo", nil, 4.2)).children {
    switch(property) {
        case (let label as String, Optional<Any>.some(let x)): 
            print("property \(label) is not nil (value: \(x))")
        case (let label as String, _): print("property \(label) is nil")
        default: ()
    }
}
/* property myString is not nil (value: foo)
   property myInt is nil
   property myDouble is not nil (value: 4.2) */

答案 1 :(得分:0)

我们可以通过直接测试其类型来避免使用StringString(describing: value)投射到value as? String

for (label, value) in properties {
  if !(value is String) {
    print("Property \(label!) is nil")
  }
}

enter image description here

答案 2 :(得分:0)

您无法将Any投射到Any?类型。很遗憾,Any无法与nil进行比较,因为它实际上是持有Optional<T>的枚举nil

不要尝试将Any投射到可选类型Any?,而是将Any中已有的可选类型转换为String类型。您应该使用带有类型转换的可选绑定:

for property in properties {
    if let value = property.value as? String {
        print ("property \(property.label!) is not nil");
    } else {
        print ("property \(property.label!) is nil");
    }
}

Any类型可以包含任何内容,包括选项,因为它们实际上是一个枚举类型(Optional<T>),用于评估case nonecase some(T)。所以nil实际上是其中一种情况:

nil == Optional<T>.none // Always returns true

因此,不要将Any类型评估为nil,而是尝试使用可选绑定。如果成功则没有nil,如果它确实没有nil

答案 3 :(得分:0)

我知道这不是最好的答案。但它可以解决你的问题。

正如prodevmx所说,

nil == Optional.none //始终返回true

所以你不能只检查

if let value = property.value as? Any  {
}

此条件始终通过,“任何”它不是可选值。

请使用此功能

func checkAnyContainsNil(object : Any) -> Bool {
    let value = "\(object)"
    if value == "nil" {
       return true
    }
    return false
 }

将对象转换为nil字符串并检查字符串是否为nil