问题 确定Any.Type是否为可选


我正在尝试确定是否给定类型 t (Any.Type)是一个可选类型,我正在使用此测试

t is Optional<Any>.Type

但它总是返回false。

有没有办法实现这个目标?


12206
2017-09-12 07:39


起源



答案:


假设你要做的是这样的:

let anyType: Any.Type = Optional<String>.self
anyType is Optional<Any>.Type // false

目前可悲的是(从Swift 2开始)不支持 协方差或逆变 并直接键入检查 Optional.Type 无法完成:

// Argument for generic parameter 'Wrapped' could not be inferred
anyType is Optional.Type // Causes error

另一种方法是制作 Optional 扩展特定协议,并检查该类型:

protocol OptionalProtocol {}

extension Optional : OptionalProtocol {}

let anyType: Any.Type = Optional<String>.self
anyType is OptionalProtocol.Type // true

11
2017-09-25 06:56



该 OptionalProtocol 可以有一些很好的用途:它可以用来提供 一个 一般的少 用于访问Optional值的接口 和 甚至包裹式。 - LopSae


答案:


假设你要做的是这样的:

let anyType: Any.Type = Optional<String>.self
anyType is Optional<Any>.Type // false

目前可悲的是(从Swift 2开始)不支持 协方差或逆变 并直接键入检查 Optional.Type 无法完成:

// Argument for generic parameter 'Wrapped' could not be inferred
anyType is Optional.Type // Causes error

另一种方法是制作 Optional 扩展特定协议,并检查该类型:

protocol OptionalProtocol {}

extension Optional : OptionalProtocol {}

let anyType: Any.Type = Optional<String>.self
anyType is OptionalProtocol.Type // true

11
2017-09-25 06:56



该 OptionalProtocol 可以有一些很好的用途:它可以用来提供 一个 一般的少 用于访问Optional值的接口 和 甚至包裹式。 - LopSae


派对有点晚了。但是,我遇到了同样的问题。这是我的代码。

func isOptional(_ instance: Any) -> Bool {
    let mirror = Mirror(reflecting: instance)
    let style = mirror.displayStyle
    return style == .optional
}

let a: Int = 1 // false
let b: Int? = 2 // true
let c: Double = 3.0 // false
let d: Double? = 4.0 // true
let e: NSString = "Hello" // false
let f: NSString? = "Hello" // true


isOptional(a) // fasle
isOptional(b) // true - warning
isOptional(c) // false
isOptional(d) // true - warning
isOptional(e) // false
isOptional(f) // true - warning

这对我来说很好看。 swift4


2
2018-02-08 17:00





您可以使用泛型来实现此目的:

func isOptional<T>(x:T?)->Bool
{
    return true
}

func isOptional<T>(x:T)->Bool
{
    return false
}

编辑

上面的代码可用于了解变量是否为可选类型。 我已经想出了解变量的唯一方法  一个类型是使用反射:

var t1:Any.Type=(String?).self
var t2:Any.Type=(String).self
Mirror(reflecting: t1).description
Mirror(reflecting: t2).description

第一次调用Mirror会给出字符串 "Mirror for Optional<String>.Type",第二个给出 "Mirror for String.Type"

我明白比较字符串不是一个方便的方法来做这个检查,我会再次尝试找到更高性能的东西..


-3
2017-09-15 16:13



t 永远不是一个可选项,它始终是一个类型对象(可能代表一个可选项),因此总是会调用第二个方法。 - idmean
对不起,我正在努力寻找有用的东西 - hariseldon78