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?
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>()