2

I would like to write an extension to array of generic type in swift. This is how I tried to do this:

class Observer<Type> {
    private(set) weak var observer: AnyObject?
    private var listener: (_ newValue: Type) -> ()

    init(observer: AnyObject, listener: @escaping (_ newValue: Type) -> ()) {
        self.observer = observer
        self.listener = listener
    }
}

extension Collection where Iterator.Element == Observer<Type> {
    func foo<Type>(value: Type) {
        forEach { $0.listener(value) }
    }
}

I would like to be able to execute function with parameter of this generic type. Is there any way to write such extension? Later this would look something like this:

let observers = [Observer<Int>]()
observers.forEach { $0.foo(4) }

1 Answer 1

1

Your example doesn't match your implementation. What is foo? And how does it relate to a? I'm going to make a guess here that you mean this to be:

extension Collection where Iterator.Element == Observer<Type> {
    func foo<Type>(value: Type) {
        forEach { $0.listener(value) }
    }
}

And then later:

let observers = [Observer<Int>]()
observers.foo(value: 4)

You cannot attach an extension to a Collection based on a specific Element. That's a restriction on extensions that has nothing to do with whether Observer is generic. You can't use == in the where clause. But you can use a protocol.

protocol Observing {
    associatedtype ObservingType

    var listener: (_ newValue: ObservingType) -> () { get }
}

Then mark Observer as Observing:

class Observer<ObservingType>: Observing {
    private(set) weak var observer: AnyObject?
    var listener: (_ newValue: ObservingType) -> ()

I've made two other changes. I swapped Type for ObservingType because Type is a keyword (so it's a bit confusing). Also, listener cannot be private unless the extension is also private.

OK, given that:

extension Collection where Iterator.Element: Observing {
    func foo(value: Iterator.Element.ObservingType) {
        forEach { $0.listener(value) }
    }
}

let observers = [Observer<Int>]()
observers.foo(value: 4)
Sign up to request clarification or add additional context in comments.

1 Comment

You're right a() was suppose to be foo() - corrected. And that's it, using associatedtype and protocol was what I needed. Thank you.

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.