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

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

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

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

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

func handle<T>(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<Any>.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 }
    }
}
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容