swift 确定“Any.Type”是否为可选

dly7yett  于 2022-11-21  发布在  Swift
关注(0)|答案(6)|浏览(256)

我试图确定一个给定的类型tAny.Type)是否是可选类型,我使用这个测试

t is Optional<Any>.Type

但它总是返回false。
那么有没有办法做到这一点呢?

8nuwlpux

8nuwlpux1#

假设你要做的事情是这样的:

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

遗憾的是,swift目前(从Swift 2开始)不支持covariance nor contravariance,并且不能直接对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
hs1ihplo

hs1ihplo2#

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

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

我觉得不错

b0zn9rqh

b0zn9rqh3#

您可以执行以下操作:

extension Mirror {
    static func isOptional(any: Any) -> Bool {
        guard let style = Mirror(reflecting: any).displayStyle,
            style == .optional else { return false }
        return true
    }
}

用法:

XCTAssertTrue(Mirror.isOptional(any: Optional(1)))

或者如果需要从Any强制转换为Optional

protocol _Optional {
    var isNil: Bool { get }
}

extension Optional: _Optional {
    var isNil: Bool { return self == nil }
}

func isNil (_ input: Any) -> Bool {
    return (input as? _Optional)?.isNil ?? false
}

用法:

isNil(nil as String?) // true
isNil("") // false
plupiseo

plupiseo4#

选项符合ExpressibleByNilLiteral,因此您可以使用:

let t = Optional<String>.self
t is ExpressibleByNilLiteral.Type // true
ylamdve6

ylamdve65#

您可以:
第一个

2fjabf4q

2fjabf4q6#

您可以使用泛型来达成此目的:

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"
我知道比较字符串不是一个方便的方法来做这个检查,我会再试一次,以找到更好的性能。

相关问题