前提: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 }
}
}