在 Swift 2 中,Array
符合CollectionType
,它定义了要求:
/// Returns the element at the given `position`.
public subscript (position: Self.Index) -> Self.Generator.Element { get }
Array
通过像这样实现它来满足这个要求:
public struct Array<Element> : CollectionType, MutableCollectionType, _DestructorSafeContainer {
// ...
// Swift can infer that Self.Index == Int & Self.Generator.Element == Element
public subscript (index: Int) -> Element
// ...
}
这允许 Swift 推断出Array
通用占位符类型Element
用于满足关联类型Self.Generator.Element
,而具体类型Int
用于满足关联类型Self.Index
。
这利用了这样一个事实,即在符合该协议的给定类型中实现协议要求时使用的类型可以隐式满足关联类型。例如,在您的情况下:
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
}
当然,如果没有使用 的协议要求associatedtype
,则必须明确满足 a typealias
:
protocol Animal {
associatedtype Breed
}
struct Dog<T> : Animal{
typealias Breed = T
}