Steffen D. Sommer
Steffen D. Sommer

Reputation: 2926

Extending custom type where associated type is equal to Void

I'm in a situation where I have a custom type that contains an associatedtype. In the case where this is equal to Void, I would like to have some default behaviour (to make the call-site more convenient). I tried to boil the example down to:

protocol FooType {
    associatedtype T: Any
    var bar: (String) -> T { get }
}

struct Foo<T>: FooType {
    let bar: (String) -> T
}

extension Foo where T == Void { // Compile error: "Same-type requirement makes generic parameter 'T' non-generic".
    init() {
        self.bar = { _ in return }
    }
}

The idea is that, in the cases where the generic type is Void, it doesn't make sense (in my scenario) to pass in a function (named bar in the example). Therefore, I just want a default implementation for this function in this specific context.

When trying to do the above I get the Same-type requirement makes generic parameter 'T' non-generic which sounds very similar to what happens when one tries to restrict e.g. the Array type when containing specific types. A workaround for this is to introduce a protocol, but I cannot do that for Void. Is it possible to do what I want or is this currently a limitation in Swift 3?

Upvotes: 3

Views: 863

Answers (1)

Steffen D. Sommer
Steffen D. Sommer

Reputation: 2926

As of Swift 3.1, the code posted in the question now works. That is, the following now works as wanted:

protocol FooType {
    associatedtype T: Any
    var bar: (String) -> T { get }
}

struct Foo<T>: FooType {
    let bar: (String) -> T
}

extension Foo where T == Void { 
    init() {
        self.bar = { _ in return }
    }
}

let foo = Foo<String>(bar: { (t: String) in return "" })
let zoo = Foo<Void>()

Upvotes: 2

Related Questions