¿Cuál es la diferencia entre Any, Hashable, AnyHashable en Swift 3?

Me rasco la cabeza a través de un montón de tutorial para entender la diferencia entre más de 3 términos y encontrar un nuevo type erased contenedor type erased términos, ahora me resulta confuso. Surgen muchas preguntas.

¿Por qué Swift introduce AnyHashable ?

¿Cuál es la diferencia fundamental entre estos 3 términos?

¿Diferencia entre Any y AnyHashable ?

¿Diferencia entre Hashable y AnyHashable ?

¿Cuándo usar Hashable y cuándo a AnyHashable ?

Último pero más confuso, ¿Qué significa el término type erased de type erased en el context de AnyHashable ?

Seguí la Propuesta Swift Evolution SE-0131 .

Es más importante comprender qué son que cuáles son las diferencias entre ellos.

Any significa "cualquier cosa", que van desde lists rápidas, tuplas, cierres, estructuras, classs, protocolos, lo que sea. Cada tipo se puede asignar a una variable de tipo Any .

Hashable es un protocolo que dice "este object puede ser hashed, es decir, tiene un hashcode". Si su object puede ser hash, aplique este protocolo, porque muchas estructuras de datos (es decir, dictionarys y sets) lo necesitan.

Entonces, ¿qué es AnyHashable ?

Normalmente, si intentas hacer esto:

 let a: Set<Hashable>? 

no comstack Esto se debe a que Hashable henetworkinga de Equatable que contiene Self .

Ahora, digamos que desea portar un método desde Objective-C a Swift. Ese método toma un parámetro del tipo NSSet . En Swift, esto se convertirá en un Set , pero ¿cuál es su parámetro genérico? Si ponemos Any como lo hacemos con NSArray , no funciona porque los objects de Set deben ser hashable. Pero si ponemos Set<Hashable> tampoco funciona porque Hashable solo puede usarse como una restricción genérica. Es por eso que envolvieron Hashable con un AnyHashable que no usa Self y, por lo tanto, se puede usar como un parámetro genérico.

Con respecto a lo que "tipo borrado" significa:

Tener Self en un protocolo es algo así como un protocolo con un parámetro genérico, y el parámetro genérico siempre es la class conforme. Esto hace que los protocolos no puedan utilizarse por sí solos como Set<Hashable> porque se desconoce el "parámetro genérico". AnyHashable resuelve este problema al no utilizar Self en absoluto, por lo que ahora se convierte en una estructura normal. "Borra" el tipo genérico de Self .