In Swift 2.3 where does Array define the Element associated type ?
It has to define it because it implements GeneratorType which has Element an associated Type. Dictionary and Set both define Element but where does Array define it ?
Array has a generic type called Element, does having a generic type satisfy the GeneratorType protocol ?
I tried this out in the playground and it doesn't work out for me.
For example
protocol Animal{
associatedtype Breed
}
struct Dog<Breed>: Animal{
}
In Swift 2, Array
conforms to CollectionType
, which defines the requirement:
/// Returns the element at the given `position`.
public subscript (position: Self.Index) -> Self.Generator.Element { get }
Array
satisfies this requirement by implementing it like so:
public struct Array<Element> : CollectionType, MutableCollectionType, _DestructorSafeContainer {
// ...
// Swift can infer that Self.Index == Int & Self.Generator.Element == Element
public subscript (index: Int) -> Element
// ...
}
This allows Swift to infer that Array
's generic placeholder type Element
is used to satisfy the associated type Self.Generator.Element
, and the concrete type Int
is used to satisfy the associated type Self.Index
.
This takes advantage of the fact that associated types can be satisfied implicitly by the type used in the implementation of a protocol requirement in a given type that conforms to that protocol. For example, in your case:
protocol Animal {
associatedtype Breed
var breed : Breed { get }
}
// I've named the generic placeholder T to simply make clear that Swift is inferring
// T == Breed and therefore satisfying the associatedtype requirement.
// You can rename the generic placeholder back to 'Breed' – the compiler will still
// infer that it's satisfying the Breed associatedtype.
struct Dog<T> : Animal{
let breed : T
}
enum BreedOfCat {/* ... */}
struct Cat : Animal {
// same principle with non-generic types: BreedOfCat == Breed
let breed : BreedOfCat
}
Although of course, if there are no protocol requirements that use the associatedtype
, it'll have to be satisfied explicitly with a typealias
:
protocol Animal {
associatedtype Breed
}
struct Dog<T> : Animal{
typealias Breed = T
}