Magoo
Magoo

Reputation: 2619

convenience method for combine publishers

I find myself wanting the same functionality in Combine quite often, so I wanted to make a convenience method like so...

public extension Published.Publisher {
    func sinkChanges(receiveValue: @escaping (Self.Output) -> Void) -> AnyCancellable {
        self.dropFirst()
            .removeDuplicates()
            .sink(receiveValue: closure)
    }
}

However I'm pretty new to the syntax and I get the error

Referencing instance method 'removeDuplicates()' on 'Publisher' requires that 'Publishers.Drop<Published<Value>.Publisher>.Output' (aka 'Value') conform to 'Equatable'

I understand why and what I have to do, just no idea syntactically where it goes...

My best guess so far was public extension Published.Publisher where Output: Equatable { but it didn't like that... what should I be searching for?

Upvotes: 1

Views: 389

Answers (1)

lazarevzubov
lazarevzubov

Reputation: 2285

TL;DR. Your best guess is correct.


As you might've noticed (and according to documentation), the method removeDuplicates() is only available, when Output conforms to Equatable. If you want to use this method in your extension, you must guarantee that. And to do that, you can add a constraint exactly as you described:

import Combine

public extension Published.Publisher where Output: Equatable {
  func sinkChanges(receiveValue: @escaping (Output) -> Void) -> AnyCancellable {
    dropFirst().removeDuplicates().sink(receiveValue: receiveValue)
  }
}

There's nothing wrong with extension constraints, it's a language feature. Here's one post about it.

Upvotes: 1

Related Questions