代码之家  ›  专栏  ›  技术社区  ›  William Hu

具有协议元素的数组不能调用数组扩展方法

  •  0
  • William Hu  · 技术社区  · 6 年前

    错误:“ObjectProtocol”类型不符合“equalable”协议

    extension Array {
        func good() {
        }
    }
    
    protocol ObjectProtocol {
    
    }
    
    extension ObjectProtocol where Self: Equatable  {
       func isEqualTo(_ other: ObjectProtocol) -> Bool {
           guard let otherX = other as? Self else { return false }
           return self == otherX
       }
    }
    
    extension Array where Element: Equatable {
        func bad() {}
    }
    
    var protocolArray = [ObjectProtocol]()
    var array = [1,3,2,5]
    
    array.good() // OK
    array.bad() // OK
    
    protocolArray.good() // OK
    protocolArray.bad() // error: error: type 'ObjectProtocol' does not conform to protocol 'Equatable'
    

    有什么办法可以实现吗?

    0 回复  |  直到 6 年前
        1
  •  1
  •   Marc    6 年前

    你的 Equatable 一致性是Objective-C版本,而不是Swift版本。

    protocol FoobarProtocol: Equatable {}
    
    extension FoobarProtocol {
        public static func == (lhs: Self, rhs: Self) -> Bool {
            return true // do something useful
        }
    }
    

    协议 Array 具有附加一致性的元素。这将导致另一个错误:

    错误:不支持将“FoobarProtocol”用作符合协议“equalable”的具体类型

    相等的 一致性只是对另一个协议的一致性。默认实现 static func == (lhs:rhs:) 在具体类型采用该协议之前,它仍然是一致的。 当协议在具体实现中使用时,默认实现会自动唤醒。

    Swift中的协议不可等同。只有具体的类型才能相等。

    备选方案

    1. 继承 结构
    2. 利用 具有 班级
    3. 创建 包装对象
        2
  •  0
  •   adri    6 年前

    在数组扩展中实现的函数仅对可计算类型可用。在您的ObjectProtocol扩展中实现的函数也只适用于equalable类型,但这并不意味着符合ObjectProtocol的对象也将符合equalable。为了做到这一点,你可以这样做:

    class Custom<T: ObjectProtocol & Equatable>{
        var array = [T]()
    
        func doStuff(){
        array.bad()
        }
    }
    
        3
  •  0
  •   Marc    6 年前

    错误:“ObjectProtocol”类型不符合“equalable”协议

    扩展您要添加的约束 Self Equatable .

    protocol ObjectProtocol {}
    
    extension ObjectProtocol where Self: Equatable  {
        func isEqualTo(_ other: ObjectProtocol) -> Bool {
            guard let otherX = other as? Self else { return false }
            return self == otherX
        }
    }
    
    extension Array where Element: Equatable {
        func bad() {
            print("I am bad")
        }
    }
    
    extension Array {
        func good() {
            print("I am good")
        }
    }
    // I have added a custom Type `Friend` and confirm it to the `ObjectProtocol` and Equatable
    struct Friends: ObjectProtocol, Equatable{
        var years = 10
    }
    
    var protocolArray = [Friends]()
    //protocolArray.append(Friends(name: 29))
    //protocolArray.append(Friends(name: 50))
    var array = [1, 3, 2, 5]
    
    array.good() // OK
    array.bad() // OK
    
    protocolArray.good() // OK
    protocolArray.bad() // It will work now