Wiem tylko o TypeTags, że w jakiś sposób zastąpiły Manifesty. Informacje w Internecie są rzadkie i nie dają mi dobrego zrozumienia tematu.
Byłbym szczęśliwy, gdyby ktoś udostępnił link do przydatnych materiałów na TypeTags, w tym przykładów i popularnych przypadków użycia. Mile widziane są także szczegółowe odpowiedzi i wyjaśnienia.
scala
types
scala-2.10
reification
Sergey Weiss
źródło
źródło
Odpowiedzi:
TypeTag
Rozwiązuje problem, że typy Scala są usunięte w czasie wykonywania (typ skasowaniem). Jeśli chcemyotrzymamy ostrzeżenia:
Aby rozwiązać ten problem, do Scali wprowadzono manifesty . Ale problem polega na tym, że nie mogą reprezentować wielu użytecznych typów, takich jak typy zależne od ścieżki:
Dlatego są one zastępowane przez TypeTags , które są zarówno znacznie prostsze w użyciu, jak i dobrze zintegrowane z nowym interfejsem API Reflection. Dzięki nim możemy elegancko rozwiązać powyższy problem dotyczący typów zależnych od ścieżki:
Są również łatwe w użyciu, aby sprawdzić parametry typu:
W tym momencie niezwykle ważne jest zrozumienie używania
=:=
(równości typów) i<:<
(relacji podtypów) do kontroli równości. Nigdy nie używaj==
lub!=
, chyba że absolutnie wiesz, co robisz:Ten ostatni sprawdza równość strukturalną, co często nie jest tym, co należy zrobić, ponieważ nie przejmuje się takimi rzeczami, jak przedrostki (jak w przykładzie).
A
TypeTag
jest całkowicie generowany przez kompilator, co oznacza, że kompilator tworzy i wypełnia a,TypeTag
gdy wywołuje metodę oczekującą takiegoTypeTag
. Istnieją trzy różne formy tagów:ClassTag
zastępuje,ClassManifest
podczas gdyTypeTag
mniej więcej zastępujeManifest
.Ten pierwszy pozwala na pełną pracę z rodzajowymi tablicami:
ClassTag
zawiera tylko informacje potrzebne do tworzenia typów w czasie wykonywania (które są usuwane z typów):Jak widać powyżej, nie przejmują się usuwaniem typów, dlatego jeśli chcemy mieć „pełne” typy,
TypeTag
należy użyć:Jak widać, metoda
tpe
zTypeTag
wynikami w pełnymType
, która jest taka sama otrzymujemy gdytypeOf
jest tzw. Oczywiście możliwe jest użycie zarówno, jakClassTag
iTypeTag
:Pozostaje pytanie, jakie jest sens
WeakTypeTag
? Krótko mówiąc,TypeTag
reprezentuje konkretny typ (oznacza to, że zezwala tylko na typy w pełni tworzone), aWeakTypeTag
po prostu zezwala na dowolny typ.TypeTag
Przez większość czasu nie dba się o to, co jest (co oznacza, że należy użyć), ale na przykład, gdy używane są makra, które powinny działać z typami rodzajowymi, są one potrzebne:Jeśli jeden zamienia
WeakTypeTag
się,TypeTag
generowany jest błąd:Aby uzyskać bardziej szczegółowe wyjaśnienie różnic między
TypeTag
iWeakTypeTag
zobacz to pytanie: Makra Scala: „nie można utworzyć znacznika TypeTag z typu T o nierozwiązanych parametrach typu”Oficjalna strona dokumentacji Scali zawiera również przewodnik do Refleksji .
źródło
==
dla typów reprezentuje równość strukturalną, a nie równość odniesienia.=:=
wziąć pod ekwiwalencyjne typ konta (nawet bez oczywistych, takich jak ekwiwalencyjne przedrostków, które pochodzą z różnych lustrach), 2) ZarównoTypeTag
iAbsTypeTag
są oparte na lustrach. Różnica polega na tym, żeTypeTag
zezwala tylko na typy w pełni tworzone (tj. Bez żadnych parametrów typu lub odniesień do elementów typu abstrakcyjnego), 3) Szczegółowe wyjaśnienie znajduje się tutaj: stackoverflow.com/questions/12093752Int
i typy ogólne, takie jakList[Int]
), pomijając takie typy Scala, jak np. Udoskonalenia, typy zależne od ścieżki, elementy egzystencjalne, typy z adnotacjami. Manifestacje również są na wyciągnięcie ręki, więc nie mogą korzystać z ogromnej wiedzy, którą kompilator ma do powiedzenia, powiedzmy, obliczenia linearyzacji typu, sprawdzenia, czy jeden typ jestTypes.scala
(7kloc kodu, który wie, w jaki sposób obsługiwane są typy),Symbols.scala
(3kloc kodu, który wie, jak działają tabele symboli) itp.ClassTag
jest dokładnym zamiennikiemClassManifest
, podczas gdyTypeTag
mniej więcej zastępujeManifest
. Mniej więcej dlatego, że: 1) znaczniki typu nie niosą wymazań, 2) manifesty to duży hack, a zrezygnowaliśmy z emulowania jego zachowania za pomocą znaczników typu. # 1 można naprawić za pomocą obwiedni kontekstu ClassTag i TypeTag, gdy potrzebujesz zarówno wymazań, jak i typów, a zwykle nie przejmuje się tym # 2, ponieważ możliwe jest wyrzucenie wszystkich hacków i użycie pełnoprawnego API odbicia zamiast.