美文网首页Swift
Swift 4.1 - SE-0143 Conditional

Swift 4.1 - SE-0143 Conditional

作者: ienos | 来源:发表于2020-12-02 16:10 被阅读0次

Base In Extension

如果需要为某个 Struct / Classes / Enum 扩展方法,然后并需要为其添加约束(泛型遵循某个协议)

eg: extension Array where Element: TextRepresentable

一、Motivation

我们来举一个例子

假设说我们要为 Array,扩展一个方法,这个方法是当数组中的元素 Element 遵循某个协议 P 的时候才能使用

如果是以前的写法,需要对所有元素进行一个类型的判断 element as? P

protocol P {
    func doSomeThing() 
}

extension Array: P {
    
    func doSomeThing() {
        for element in self {
            if let pElement = element as? P {
                pElement.doSomeThing()                
            }else {
                print("element is not P")
            }
        }
    }
}

如果在 Swift 4.1, 使用 Conditional Conformance

protocol P {
    func doSomeThing() 
}

extension Array: P where Element: P {
   
    func doSomeThing() {
        for element in self {
            element.doSomeThing()
        }
    }
}

二、Multiple conformances

Swift 中禁止同一类型遵循同一协议两次

protocol P {}
struct X: P {}
extension: P {} // error: X already stated conformance to P

同样的对于 Conditional Conformance, 也同样禁止

protocol HashIdentify {
    static func ===(lhs: Self, rhs: Self) -> Bool
}

struct SomeWrapped<Wrapped> { 
    var wrapped: Wrapped 
}

extension SomeWrapped: Equatable where Wrapped: Equatable {
    static func ==(lhs: SomeWrapped<Wrapped>, rhs: SomeWrapped<Wrapped>) -> Bool {
        return lhs.wrapped == rhs.wrapped
    }
}
/* SomeWrapped already stated conformance to Equtable */
extension SomeWrapped: Equtable where Wrapped: HasIdentify {
    static func ==(lhs: SomeWrapped<wrapped>, rhs: SomeWrapped<Wrapped>) -> Bool {
        return lhs.wrapped === rhs.wrapped
    }
}

很显然,SomeWrapped 不能同时拥有两个 fun == 的实现

以下行为也不允许

extension SomeWrapped: Equatable where Wrapped == Int {
    static func ==(lhs: SomeWrapped<Wrapped>, rhs: SomeWrapped<Wrapped>) -> Bool {
        return lhs.wrapped == rhs.wrapped
    }
}
/* SomeWrapped already stated conformance to Equtable */
extension SomeWrapped: Equtable where Wrapped == String {
    static func ==(lhs: SomeWrapped<wrapped>, rhs: SomeWrapped<Wrapped>) -> Bool {
        return lhs.wrapped === rhs.wrapped
    }
}

在上述的 extension 中,有可能 Wrapped: Equtable,也有可能 Wrapped: HasIdentify, 有可能两个同时满足,也有可能两个都不满足

如果是同时满足的情况,可采用 Equatable & HasIdentify

extension SomeWrapped: Equatable where Wrapped: Equatable & HasIdentify {
    static func ==(lhs: SomeWrapped<Wrapped>, rhs: SomeWrapped<Wrapped>) -> Bool {
        return lhs.wrapped == rhs.wrapped
    }
}

三、Implied conditional conformances

protocol P { }
protocol Q : P { }
protocol R : P { }

struct X<T> { }
extension X: Q where T: Q { }
extension X: R where T: R { }

因为 Q: P , R: P,所以 T: Q 和 T: R 均隐式满足 T: P

如果当 T: P 时,他同时满足两个 extension,这时候会出现不确定性,系统将会建议用户新建 T: P 的 extension

extension X: P where T: P {}

除了上述情况, 还有 T: Q, T: R 且 Q: R, R: P 的情况该如何处理

protocol P { }
protocol Q : P { }
protocol R : Q { }

struct X<T> { }
extension X: Q where T: Q { }
extension X: R where T: R { }

也就是说当,T: P 时,同样会存在不确定性,同样系统将会建议用户新建 T: P 的 extension

extension X: P where T: P {}

相关文章

网友评论

    本文标题:Swift 4.1 - SE-0143 Conditional

    本文链接:https://www.haomeiwen.com/subject/bacuwktx.html