在Swift中,以下代码编译没有问题。
protocol P1 {
associatedtype T = Int
}
protocol P2 {
typealias T = Int
}
对我来说,这些似乎表现得几乎相同。我注意到的唯一区别是,你有什么时候可以使用P1
,因为它有一个相关的类型。特别是,let x: P1
是一个错误,而let x: P2
是好的。
这两个协议之间的实际区别是什么?它们在编译代码中的处理方式不同吗最后,使用P1
而不是P2
是否有优势?
为清晰起见编辑:
我知道相关类型和类型别名之间的工作差异,所以我很惊讶您甚至可以给关联类型一个固定值。这似乎打败了相关类型的整个目的。我想知道是否有任何实用程序给关联类型一个固定值,我想知道这两个协议是否在编译后是不同的。
在您编写的代码中,没有真正的功能差异,因为您已将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中有大量关于associatedType的优秀资源......