Todo lo que sé sobre TypeTags es que de alguna manera reemplazaron Manifiestos. La información en Internet es escasa y no me proporciona un buen sentido del tema.
Por lo tanto, estaría feliz si alguien compartiera un enlace a algunos materiales útiles en TypeTags, incluidos ejemplos y casos de uso populares. Respuestas detalladas y explicaciones también son bienvenidas.
scala
types
scala-2.10
reification
Sergey Weiss
fuente
fuente
Respuestas:
A
TypeTag
resuelve el problema de que los tipos de Scala se borran en tiempo de ejecución (borrado de tipos). Si queremos hacerrecibiremos advertencias:
Para resolver este problema, se presentaron Manifiestos a Scala. Pero tienen el problema de no poder representar muchos tipos útiles, como los tipos dependientes de la ruta:
Por lo tanto, son reemplazados por TypeTags , que son mucho más simples de usar y están bien integrados en la nueva API de Reflection. Con ellos podemos resolver el problema anterior sobre los tipos dependientes de la ruta con elegancia:
También son fáciles de usar para verificar los parámetros de tipo:
En este punto, es extremadamente importante comprender el uso
=:=
(igualdad de tipos) y<:<
(relación de subtipo) para verificaciones de igualdad. Nunca use==
o!=
, a menos que sepa absolutamente lo que hace:Este último verifica la igualdad estructural, que a menudo no es lo que se debe hacer porque no le importan cosas como los prefijos (como en el ejemplo).
A
TypeTag
está completamente generado por el compilador, eso significa que el compilador crea y completa unTypeTag
cuando se llama a un método que espera talTypeTag
. Existen tres formas diferentes de etiquetas:ClassTag
sustituyeClassManifest
mientras queTypeTag
es más o menos el reemplazo deManifest
.El primero permite trabajar completamente con matrices genéricas:
ClassTag
proporciona solo la información necesaria para crear tipos en tiempo de ejecución (que se borran):Como se puede ver arriba, no les importa el borrado de tipos, por lo tanto, si se desea
TypeTag
usar tipos "completos" :Como se puede ver, el método
tpe
deTypeTag
resultados es completoType
, que es lo mismo que obtenemos cuandotypeOf
se llama. Por supuesto, es posible usar ambosClassTag
yTypeTag
:La pregunta que queda ahora es ¿cuál es el sentido de
WeakTypeTag
? En resumen,TypeTag
representa un tipo concreto (esto significa que solo permite tipos completamente instanciados) mientras queWeakTypeTag
solo permite cualquier tipo. La mayoría de las veces a uno no le importa qué es qué (qué mediosTypeTag
deben usarse), pero, por ejemplo, cuando se usan macros que deberían funcionar con tipos genéricos, se necesitan:Si se reemplaza
WeakTypeTag
conTypeTag
un error se arroja:Para obtener una explicación más detallada sobre las diferencias
TypeTag
yWeakTypeTag
ver esta pregunta: Macros Scala: "no se puede crear TypeTag a partir de un tipo T que tenga parámetros de tipo sin resolver"El sitio de documentación oficial de Scala también contiene una guía para Reflection .
fuente
==
para los tipos representa la igualdad estructural, no la igualdad de referencia.=:=
tener en cuenta las equivalencias de tipo (incluso las no obvias, como las equivalencias de prefijos que provienen de diferentes espejos), 2) AmbosTypeTag
yAbsTypeTag
se basan en espejos. La diferencia es queTypeTag
solo permite tipos completamente instanciados (es decir, sin ningún tipo de parámetros o referencias de miembros de tipo abstracto), 3) Una explicación detallada está aquí: stackoverflow.com/questions/12093752Int
y tipos genéricos comoList[Int]
), dejando de lado tales tipos de Scala como, por ejemplo, refinamientos, tipos dependientes de ruta, existenciales, tipos anotados. Además, los manifiestos son un obstáculo, por lo que no pueden usar el vasto conocimiento que posee el compilador para, por ejemplo, calcular la linealización de un tipo, averiguar si un tipo subtipa a otro, etc.Types.scala
(7kloc de código que sabe cómo se admiten los tipos para trabajar juntos),Symbols.scala
(3kloc de código que sabe cómo funcionan las tablas de símbolos), etc.ClassTag
es un reemplazo directo exacto paraClassManifest
, mientras queTypeTag
es más o menos un sustituto deManifest
. Más o menos, porque: 1) las etiquetas de tipo no llevan borrados, 2) los manifiestos son un gran truco, y dejamos de emular su comportamiento con etiquetas de tipo. El n. ° 1 se puede solucionar mediante el uso de límites de contexto ClassTag y TypeTag cuando necesita tanto borrados como tipos, y uno generalmente no se preocupa por el n. ° 2, porque es posible deshacerse de todos los hacks y usar la API de reflexión completa en lugar.