I created a function with generics
func sorted<T: MyProtocol>(array: [T]) -> [T] { ... }
and trying to call in
let array: [MyProtocol] = [...]
let sortedArray = sorted(array: array)
But getting the error
Type 'any MyProtocol' cannot conform to 'MyProtocol'
I understand that variable array
is a box that can contain any kind of thing that conforms to the MyProtocol
. But how I can resolve this problem ? I need to sorted any kind of MyProtocol
Tried something like this, but do not working
func sorted<T: any MyProtocol>(array: [T]) -> [T] { ... }
CodePudding user response:
I understand that variable
array
is a box that can contain any kind of thing that conforms to theMyProtocol
.
That's exactly the problem with your code. When you wrote let array: [MyProtocol]
, rather than having an array of some concrete type that adopts the MyProtocol
protocol, it is actually an array of an existential type that can store any objects that adopt the MyProtocol
protocol, and such existential type does not adopt the protocol itself.
However, when you wrote the generic function func sorted<T: MyProtocol>
, you specifically constrained the type T
to be some type that adopts MyProtocol
. Since the existential type itself does not adopt the protocol, you received the error.
To solve the problem, instead of constraining the function sorted
, you can make the parameter itself and the return value an array of the existential type:
func sorted(array: [MyProtocol]) -> [MyProtocol]
Sidenote, starting from Swift 5.6, usages of existential types should be explicitly denoted, so your array
declaration would become:
let array: [any MyProtocol] = [...]
And the function signature would become:
func sorted(array: [any MyProtocol]) -> [any MyProtocol]
CodePudding user response:
If you want to add a function to Array
based on the Element
you could do that by extending the array...
extension Array where Element: MyProtocol {
func sorted() -> [Element] {
// put your sorting logic here that uses the `MyProtocol` properties.
}
}
Having said that though... if you can sort objects that conform to your MyProtocol
. Then that protocol also will probably conform to Comparable
.
And there is already a sorted
function on [Comparable]
(Array of objects conforming to Comparable
). So you wouldn't need a new function for that.
To make that work you could define your protocol like...
protocol MyProtocol: Comparable {
}
This will then give your array the .sorted()
function.
Documentation on Comparable... https://developer.apple.com/documentation/swift/comparable
CodePudding user response:
The error message is indicating that the type of the elements in the array variable, any MyProtocol, is not the same as the type specified in the sorted function's generic constraint, MyProtocol.
In Swift, any is a protocol that all types conform to. So any MyProtocol is a type that conforms to both the any and MyProtocol protocols.
To fix this error, you can either change the type of the array variable to [MyProtocol] or change the constraint of the sorted function to T: any MyProtocol.