I'm trying to get to work a Swift Extension with two generic types. I tried to make an example.
We have a Box where we can for different types.
class Box<E> {
var value: E
init(val: E) {
value = val
}
}
Now we have a special Itemtype which can again have different types
class Item<Type> {
var value: Type
init(val: Type) {
value = val
}
}
So now we can easily create an Box<Item<Int>>
. But maybe we want to change it to Box<Item<String>>
So I would like to have an extension to change from Box<Item<A>>
to Box<Item<B>>
What does work is the following
extension Box where E: Item<Any> {
func mapOnItem(function: (Any) -> Any) -> Box<Item<Any>> {
return Box<Item<Any>>(val: Item(val: function(value.value)))
}
}
But this is not very useful because we don't have the connection from the function return value to the mapOnItem return value.
So I tried to fix but I'm failing. My understanding would be to introduce another generic variable here.
extension Box<A> where E: Item<A> {
func mapOnItem<B>(function: (A) -> B) -> Box<Item<B>> {
return Box<Item<B>>(val: Item(val: function(value.value)))
}
}
I'm getting the error
Constrained extension must be declared on the unspecialized generic type 'Box' with constraints specified by a 'where' clause
Do you have any clues for me? Is it even possible?
Thanks for your help
Martin
A constraint on the extension can restrict the placeholder type E
to concrete types or protocols, for example:
extension Box where E: Item<Any> {}
extension Box where E == String {}
extension Box where E: Numeric {}
But you cannot put a generic constraint on the extension:
extension Box<A> where E: Item<A> {}
// Error: Constrained extension must be declared on the unspecialized generic
// type 'Box' with constraints specified by a 'where' clause
The solution is to restrict the method instead:
extension Box {
func mapOnItem<A, B>(function: (A) -> B) -> Box<Item<B>> where E: Item<A> {
return Box<Item<B>>(val: Item(val: function(self.value.value)))
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With