Swift 3 中 Any 、 Hashable 、 AnyHashable 之间有什么区别?

What is difference between Any , Hashable , AnyHashable in Swift 3?

我通过大量教程摸索着理解上述 3 个术语之间的区别,并找到了新术语 type erased 容器,现在它让我感到困惑。它提出了很多问题。

为什么Swift引入AnyHashable

这 3 个术语之间的根本区别是什么?

AnyAnyHashable 的区别?

HashableAnyHashable 的区别?

何时使用 Hashable 以及何时使用 AnyHashable ?

最后但也是最令人困惑的是,type erased 术语在 AnyHashable 上下文中的含义是什么?

作为上下文,我遵循了Swift Evolution Proposal SE-0131

了解它们是什么比了解它们之间的区别更重要。

Any 表示 "anything",范围从 swift 枚举、元组、闭包、结构、classes、协议等等。每种类型都可以分配给 Any.

类型的变量

Hashable 是表示 "this object can be hashed i.e. has a hashcode" 的协议。如果你的对象可以被散列,实现这个协议,因为很多数据结构(即字典和集合)需要它。

那什么是AnyHashable

通常情况下,如果您尝试这样做:

let a: Set<Hashable>?

它不编译。这是因为 Hashable 继承自 Equatable 其中包含 Self.

现在,假设您要将方法从 Objective-C 移植到 swift。该方法采用 NSSet 类型的参数。在Swift中,这将变成一个Set,但它的泛型参数是什么?如果我们只是像 NSArray 那样放置 Any,那是行不通的,因为 Set 的对象必须是可散列的。但是如果我们放 Set<Hashable> 它也不起作用,因为 Hashable 只能用作通用约束。这就是为什么他们用 AnyHashable 包装 Hashable 使用 Self 因此可以用作通用参数。

关于 "type erased" 的含义:

在协议中有 Self 有点像 like a protocol with a generic parameter,通用参数总是符合要求的 class。这导致协议无法像 Set<Hashable> 一样单独使用,因为 "generic parameter" 是未知的。 AnyHashable 通过根本不使用 Self 解决了这个问题,所以它现在变成了一个普通的结构。它 "erases" 通用 Self 类型。