Swift:一个typealias和一个带有协议值的关联类型有什么区别?

问题描述 投票:0回答:1

在Swift中,以下代码编译没有问题。

protocol P1 {
    associatedtype T = Int
}

protocol P2 {
    typealias T = Int
}

对我来说,这些似乎表现得几乎相同。我注意到的唯一区别是,你有什么时候可以使用P1,因为它有一个相关的类型。特别是,let x: P1是一个错误,而let x: P2是好的。

这两个协议之间的实际区别是什么?它们在编译代码中的处理方式不同吗最后,使用P1而不是P2是否有优势?

为清晰起见编辑:

我知道相关类型和类型别名之间的工作差异,所以我很惊讶您甚至可以给关联类型一个固定值。这似乎打败了相关类型的整个目的。我想知道是否有任何实用程序给关联类型一个固定值,我想知道这两个协议是否在编译后是不同的。

swift swift-protocols type-alias associated-types
1个回答
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中有大量关于associatedType的优秀资源......

  1. Hacking With Swift
  2. Natasha the Robot
  3. Medium
© www.soinside.com 2019 - 2024. All rights reserved.