I want a function that accepts a sequence of Int
. Here is what I want to write:
func process(items: Sequence<Int>) {
items.forEach { ... }
}
Error: "Cannot specialize non-generic type 'Sequence'".
Corrected (I think):
func process<S: Sequence>(items: S) where S.Iterator.Element == Int {
items.forEach { ... }
}
Quite a bit more verbose.
I know that the Sequence protocol has an associated type of Iterator
which has Element
. But I'm not quite sure why I have to resolve the Int
requirement in such a weird way.
What are the underlying concepts that make the first version not work but the second? What does the error mean?
Your question is to do with the difference between generic types and associated types. See here (sections titled "Generic Types", "Associated Types") for a basic explanation of their purposes in Swift. Protocols, like Sequence, use associated types, rather than generic types. Your first code sample would make sense if Sequence
was a concrete class with a generic type - this difference should explain the error message.
As for why protocols use associated types, rather than generic types, see the top answer to this question. Essentially, though they seem to serve the same purpose, associated types are meant to be more flexible and descriptive, where generic types are about implementation. This makes your code sample more verbose, but overall, makes many code samples simpler.
In fact, from the Sequence source code, Sequence
has an associated type Iterator, which conforms to the IteratorProtocol protocol, which in turn has its own associated type Element (which can be any type).
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