当范型遇到可选型How to determine if a generic is an optional in Swift?

前提:Optional是一个具体类型,无法用作范型类型的约束。

问题一:使用了范型的方法里,如何知道是否是一个可选型呢?

func handle(type:T.type) throws -> T {
}
obj.handle(type:String)// T为String
obj. handle(type:String?)// T为Optional

需求:
当obj为null时,obj.handle(type:String)抛出异常,obj. handle(type:String?)返回nil
要做的是在方法里判断type是否为可选型:

func handle(type:T.type) throws -> T {
    if type is Optional {
        return nil
    }else{
        throw Error
    }
}

但是Optional是一个确切的类型,是一个包含some和none的一个结构体。你没法办知道范型T是否为Optional。
换个思路,如果nil可以转为T,则表明T是个可选型。

if let nilT = Optional.none as? T {
    return nilT
}else{
    throw Error
}

...

问题二:给数组添加一个移除nil元素的方法,使用范型T,如何知道该类型T是可选型且值是nil?
如何使用一个够约束范型为Optional的协议呢?

新建一个协议,然后让Optional遵守这个协议。

public protocol OptionalType: ExpressibleByNilLiteral {
    associatedtype WrappedType
    var asOptional: WrappedType? { get }
}
extension Optional: OptionalType {
    public var asOptional: Wrapped? {
        return self
    }
}

在Optional扩展里,利用类型推断确定了OptionalType里范型的类型。
如此即可以通过ele.asOptional得到一个值或者nil。

public extension Sequence where Self.Iterator.Element: OptionalType {
    public func removingNils() -> [Self.Iterator.Element.WrappedType] {
        return flatMap { $0.asOptional }
    }
}

你可能感兴趣的:(当范型遇到可选型How to determine if a generic is an optional in Swift?)