在Swift中,以下代码编译没有问题。
protocol P1 {
associatedtype T = Int
}
protocol P2 {
typealias T = Int
}
在我看来,它们的行为几乎相同。我注意到的唯一区别是,P1
的使用时间还有其他限制,因为它具有关联的类型。特别是let x: P1
是错误,而let x: P2
很好。
这两种协议之间的实际区别是什么?在编译后的代码中,它们是否有所不同?最后,使用P1
而不是P2
有优势吗?
为清楚起见进行编辑:
我知道关联类型和类型别名之间的有效区别,所以令我惊讶的是,甚至允许您为关联类型提供固定值。这似乎破坏了关联类型的全部目的。我想知道是否有任何实用程序可以为关联类型赋予固定值,并且我想知道一旦编译后这两个协议是否不同。
答案 0 :(得分:2)
在您编写的代码中,实际上没有功能上的区别,因为您将associatedType
设置为Int
。
要获得更强大的用法,您可以将associatedType
用作伪通用约束。
所以您可以这样写...
protocol P1 {
associatedType Item: Equatable
var itemArray: [Item] { get set }
func add(item: Item)
}
extension P1 {
func add(item: Item) {
itemArray.append(item)
}
}
struct StructWithStrings: P1 {
var itemArray: [String]
}
struct StructWithInts: P1 {
var itemArray: [Int]
}
因为它们都符合P1并且都将其数组类型设置为Equatable
类型。编译器可以推断出add(item: Item)
函数的正确类型,并在编译时提供帮助。
与此相反,typealias
仅为了方便起见才真正用于更改某种类型的名称。例如,您可能会像... (Data?, Error?, URLResponse) -> ()
这样使用闭包,并且多次编写它会很长,但也会失去一些含义。所以你可以做...
typealias DownloadResponse = (Data?, Error?, URLResponse) -> ()
,并将所有用法替换为DownloadResponse
。
在Swift中,有很多关于relatedType的优秀资源...