Tudo o que sei sobre as TypeTags é que elas substituíram os Manifestos. As informações na Internet são escassas e não me proporcionam uma boa noção do assunto.
Então, eu ficaria feliz se alguém compartilhasse um link para alguns materiais úteis sobre TypeTags, incluindo exemplos e casos de uso populares. Respostas e explicações detalhadas também são bem-vindas.
scala
types
scala-2.10
reification
Sergey Weiss
fonte
fonte
Respostas:
A
TypeTag
resolve o problema de que os tipos do Scala são apagados no tempo de execução (apagamento do tipo). Se nós queremos fazerreceberemos avisos:
Para resolver este problema, os Manifestos foram apresentados ao Scala. Mas eles têm o problema de não poder representar muitos tipos úteis, como tipos dependentes de caminho:
Assim, eles são substituídos por TypeTags , que são muito mais simples de usar e bem integrados à nova API de reflexão. Com eles, podemos resolver o problema acima sobre tipos dependentes de caminho de maneira elegante:
Eles também são fáceis de usar para verificar os parâmetros de tipo:
Neste ponto, é extremamente importante entender o uso
=:=
(tipo igualdade) e<:<
(relação de subtipo) para verificações de igualdade. Nunca use==
ou!=
, a menos que você saiba absolutamente o que faz:O último verifica a igualdade estrutural, o que geralmente não é o que deve ser feito, porque não se importa com itens como prefixos (como no exemplo).
A
TypeTag
é completamente gerado pelo compilador, o que significa que o compilador cria e preenche umTypeTag
quando se chama um método que espera talTypeTag
. Existem três formas diferentes de tags:ClassTag
substituiClassManifest
considerando queTypeTag
é mais ou menos o substituto deManifest
.O primeiro permite trabalhar totalmente com matrizes genéricas:
ClassTag
fornece apenas as informações necessárias para criar tipos em tempo de execução (que são apagados):Como se pode ver acima, eles não se importam com o apagamento de tipo; portanto, se quisermos
TypeTag
usar tipos "completos" :Como se pode ver, o método
tpe
dosTypeTag
resultados é completoType
, o mesmo que obtemos quandotypeOf
é chamado. Obviamente, é possível usar ambos,ClassTag
eTypeTag
:A questão remanescente agora é qual é o sentido
WeakTypeTag
? Em resumo,TypeTag
representa um tipo concreto (isso significa que permite apenas tipos totalmente instanciados) enquantoWeakTypeTag
apenas permite qualquer tipo. Na maioria das vezes, não se importa com o que é (o que significa queTypeTag
deve ser usado), mas, por exemplo, quando são usadas macros que devem funcionar com tipos genéricos, são necessárias:Se alguém substituir
WeakTypeTag
porTypeTag
um erro é lançado:Para uma explicação mais detalhada sobre as diferenças entre
TypeTag
eWeakTypeTag
consulte esta pergunta: Macros Scala: "não é possível criar TypeTag a partir de um tipo T com parâmetros de tipo não resolvidos"O site oficial da documentação de Scala também contém um guia para reflexão .
fonte
==
para tipos representa igualdade estrutural, não referência a igualdade.=:=
levar em consideração equivalências de tipo (mesmo que não óbvias, como equivalências de prefixos que vêm de espelhos diferentes), 2) AmbosTypeTag
eAbsTypeTag
são baseados em espelhos. A diferença é queTypeTag
apenas tipos totalmente permite instanciados (isto é, sem quaisquer parâmetros de tipo ou referências sumário membros de tipo), 3) uma explicação pormenorizada aqui: stackoverflow.com/questions/12093752Int
e tipos genéricos comoList[Int]
), excluindo tipos Scala como, por exemplo, refinamentos, tipos dependentes de caminho, existenciais, tipos anotados. Também se manifesta são um parafuso, por isso eles não podem usar o vasto conhecimento que posesses compilador para, digamos, calcular a linearização de um tipo, descobrir se um tipo subtipos outro, etc.Types.scala
(7kloc de código que sabe como tipos são suportados para trabalhar em conjunto),Symbols.scala
(3kloc de código que sabe como símbolo mesas de trabalho), etc.ClassTag
é um substituto exato para o drop-inClassManifest
, enquantoTypeTag
é mais ou menos um substituto paraManifest
. Mais ou menos, porque: 1) as tags de tipo não carregam rasuras, 2) os manifestos são um grande hack e desistimos de emular seu comportamento com as tags de tipo. O número 1 pode ser corrigido usando os limites de contexto ClassTag e TypeTag quando você precisa de apagamentos e tipos, e geralmente não se importa com o número 2, porque torna-se possível jogar fora todos os hacks e usar a API de reflexão completa em vez de.