Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift extension on generic struct based on properties of type T

Tags:

generics

swift

If I have a generic struct like...

struct Blah<T> {
    let someProperty: T
}

Can I then extend Blah to conform to Equatable only when T is Equatable. Like...

extension Blah: Equatable where T: Equatable {
    static func == (lhs: Blah, rhs: Blah) -> Bool {
        return lhs.someProperty == rhs.someProperty
    }
}

Is this possible?

I have tried a few different ways of coding this but each gives me a slightly different error.

like image 535
Fogmeister Avatar asked Jun 16 '17 08:06

Fogmeister


1 Answers

Update: Conditional conformance has been implemented in Swift 4.1, and your code

struct Blah<T> {
    let someProperty: T
}

extension Blah: Equatable where T: Equatable {
    static func == (lhs: Blah, rhs: Blah) -> Bool {
        return lhs.someProperty == rhs.someProperty
    }
}

compiles and works as expected in Xcode 9.3.


What you are looking for is

  • SE-0143 Conditional conformances

(which in turn is part of the "Generics Manifesto"). The proposal has been accepted for Swift 4 but not yet implemented. From the proposal:

Conditional conformances express the notion that a generic type will conform to a particular protocol only when its type arguments meet certain requirements.

and a prominent example is

extension Array: Equatable where Element: Equatable {
  static func ==(lhs: Array<Element>, rhs: Array<Element>) -> Bool { ... }
}

to make arrays of equatable elements equatable, which is not possible at present. Your example is essentially

struct SomeWrapper<Wrapped> {
  let wrapped: Wrapped
}

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

from that proposal.

like image 176
Martin R Avatar answered Sep 21 '22 13:09

Martin R