我们似乎在这里谈论不同的目的。
你引用这段代码:
public struct Foo<E: Hashable>: Equatable, Collection
{
public typealias Element = E
private var array: [Element]
…
}
... 其中泛型struct Foo<E : Hashable> 有一个占位符E(这是实现Hashable 所必需的,以便用于E 的任何类型都与Collection 协议中声明的Element 参数兼容);并且struct Foo<E> 也是实现集合(通用)协议所必需的。
typealias Element = E 行用于将泛型结构的E 参数绑定到(泛型)集合协议中的Element 关联类型;仅此而已。这就是我向您提供使用类型别名的示例以帮助编译器为您提供完全实现 Collection 协议所需的缺失“抽象”方法的原因。
另一方面,您的代码:
public struct Foo<Element: Hashable>
{
private var array: [Element]
…
}
... 与实现协议无关;它只是一个带有名为 Element 的占位符参数的通用结构,它是实现 Hashable 所必需的。
这一次,该结构只包含一个数组,其中包含您使用Foo<Element> 时使用的任何元素。不需要类型别名,因为没有任何东西可以绑定 Element 占位符;它的用途与第一个示例中的 E 相同,但没有结构实现 Collection 的位。
我必须承认对@Airspeed Velocity 的代码感到困惑:
struct S<T> { typealias U = T }
typealias TA = S<Int>
let x: TA.T // 'T' is not a member type of 'TA' (aka 'S<Int>')
let y: TA.U
… 旨在实现。为什么要为已知且可用的类型T 指定类型别名U?在很多很多年的泛型编程中,我还没有遇到过这种情况,除非它是另一种编写我可能在 C# 泛型中使用过的东西的方式。
让我将 Swift 自己的 Collection 协议替换为一个专为你设计的 Dalija:
protocol DalijaCollection
{
associatedtype ItemType : Hashable // placeholder - does the same as Element from Collection
func append(item: ItemType)
func remove(item: ItemType)
var count: Int { get }
subscript(index: Int) -> ItemType { get }
}
class Stack<itemT : Hashable> : DalijaCollection
{
typealias ItemType = itemT // not needed once all the members of DalijaConnection have been implemented
lazy var items: [itemT] = .init()
func push(item: itemT)
{
items.append(item)
}
func pop() -> itemT?
{
guard let result = items.last,
let lastIndex = items.lastIndex(of: result) else
{
return nil
}
items.remove(at: lastIndex)
return result
}
func append(item: itemT)
{
items.append(item)
}
func remove(item: itemT)
{
guard let index = items.index(of: item) else
{
fatalError("item not found")
}
items.remove(at: index)
}
var count: Int
{
return items.count
}
subscript(index: Int) -> itemT
{
return items[index]
}
}
使用 DalijaCollection 版本,您可以这样做:
while stack.count > 0
{
print(stack.pop())
}
// or
for i in 0..<stack.count
{
print(stack[i])
}
... Swift 的 Collection 协议还允许您像这样使用 for…in 构造:
{
for item in stack
{
print(item)
}
}
……还有更多。