0

I want to make array with protocol elements call array extension method. The code in playground get error:

error: type 'ObjectProtocol' does not conform to protocol 'Equatable'

The code:

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'

Any way to achieve it?

1
  • Your protocol is not equatable. It just has a method which is accessible if the instance contained in it is equatable. Commented Feb 20, 2019 at 4:42

3 Answers 3

1

Your Equatable conformance is the Objective-C version rather than the Swift one.

protocol FoobarProtocol: Equatable {}

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

Your question is about protocols as Array elements with additional conformances. This will lead to another error:

error: using 'FoobarProtocol' as a concrete type conforming to protocol 'Equatable' is not supported

This is because the Equatable conformance is just a conformance on another protocol. The default implementation of static func == (lhs:rhs:) might lead to the impression that it is a full implementation but it isn't. It is still a conformance until a concrete type adopts to that protocol. The default implementation awakes automatically when the protocol is used in a concrete implementation.

In short: A protocol in Swift cannot be equatable. Only a concrete type can be equatable.

Alternative options

  1. Create a concrete type without inheritance using a struct.
  2. Make use of inheritance with classes instead of structs so you can have several concrete implementations
  3. Create a wrapper object which has a property with the protocol type
Sign up to request clarification or add additional context in comments.

1 Comment

The problem is the array isn't sure the type. Should be just the protocol type.
0

The function implemented in your Array extension is only available to equatable types. The function implemented in your ObjectProtocol extension is only available to equatable types as well but it doesn't mean that the object conforming to ObjectProtocol will conform to Equatable as well. In order to do that you could do something like this:

class Custom<T: ObjectProtocol & Equatable>{
    var array = [T]()

    func doStuff(){
    array.bad()
    }
}

Comments

0

If you look to your error it's self explanatory

error: type 'ObjectProtocol' does not conform to protocol 'Equatable'

In ObjectProtocol extension you are adding a constraint that Self needs to conform to Equatable.

Here's the fix:

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.