Stephen
Stephen

Reputation: 532

Constrain function generic parameter to associated type

Why does this fail with the following: Inheritance from non-protocol, non-class type on the function declaration line?

protocol Foo {
    associatedtype AType
}

struct Container<F: Foo> {

    let foo: F

    func doWork<S: F.AType>(s: S) { }
}

Upvotes: 0

Views: 308

Answers (1)

Milos
Milos

Reputation: 2758

Note that the following compiles:

protocol Foo {
    associatedtype A
}

struct Container<F: Foo> {

    func f(a: F.A) { }
}

However, in the case of:

struct Container<F: Foo> {

    func f<A : F.A>(a: A) { } // error: inheritance from non-protocol, non-class type
}

... the type F.A is completely unconstrained, so it may well be, say, an Int, which you cannot inherit from or conform to using the : syntax.

If you really need a more generic solution than (a: F.A) then something along these lines might do it:

protocol Bar { }

protocol Foo {
    associatedtype A : Bar
}

struct Container<F: Foo> {

    func f<A : Bar>(a: A) { }
}

You can now express any expectations about a parameter using Bar protocol.

Better still, you might be able to implement the method as an extension of Foo:

protocol Foo {
    associatedtype A

    func f(_: A) // if you want this to be a requirement
}

extension Foo /* where A is constrained so you can do something with it */ {

    func f(a: A) { }
}

Upvotes: 1

Related Questions