Все, что я знаю о TypeTags, это то, что они как-то заменили Manifests. Информация в Интернете скудна и не дает мне хорошего понимания предмета.
Так что я был бы рад, если бы кто-нибудь поделился ссылкой на некоторые полезные материалы о TypeTags, включая примеры и популярные варианты использования. Подробные ответы и объяснения также приветствуются.
scala
types
scala-2.10
reification
Сергей Вайс
источник
источник
Ответы:
TypeTag
Решает проблему , что типы в Scala стираются во время выполнения (типа стирания). Если мы хотим сделатьмы получим предупреждения:
Для решения этой проблемы в Scala были введены манифесты . Но у них проблема в том, что они не могут представлять много полезных типов, таких как path-зависимые типы:
Таким образом, они заменяются TypeTags , которые намного проще в использовании и хорошо интегрированы в новый Reflection API. С их помощью мы можем элегантно решить описанную выше проблему с типами, зависящими от пути:
Их также легко использовать для проверки параметров типа:
На этом этапе чрезвычайно важно понять, как использовать
=:=
(равенство типов) и<:<
(отношение подтипов) для проверок на равенство. Никогда не используйте==
или!=
, если вы не знаете, что делаете:Последний проверяет структурное равенство, что часто не то, что должно быть сделано, потому что он не заботится о таких вещах, как префиксы (как в примере).
A
TypeTag
полностью генерируется компилятором, это означает, что компилятор создает и заполняет,TypeTag
когда каждый вызывает метод, ожидающий такогоTypeTag
. Существуют три разные формы тегов:ClassTag
заменяет,ClassManifest
тогда какTypeTag
является более или менее заменойManifest
.Первый позволяет полностью работать с универсальными массивами:
ClassTag
предоставляет только информацию, необходимую для создания типов во время выполнения (которые стираются):Как можно видеть выше, они не заботятся об удалении типов, поэтому, если
TypeTag
нужно, нужно использовать «полные» типы :Как можно видеть, метод
tpe
изTypeTag
результатов в полном объемеType
, что то же самое мы получаем , когдаtypeOf
называется. Конечно, можно использовать как, такClassTag
иTypeTag
:Остается вопрос: в чем смысл
WeakTypeTag
? Короче говоря,TypeTag
представляет конкретный тип (это означает, что он допускает только полностью созданные экземпляры типов), тогда какWeakTypeTag
просто допускает любой тип. Большую часть времени не волнует, что именно (что означаетTypeTag
использование), но, например, когда используются макросы, которые должны работать с универсальными типами, они необходимы:Если кто-то заменит
WeakTypeTag
сTypeTag
ошибкой, выдается:Более подробное объяснение различий между ними
TypeTag
иWeakTypeTag
см. Этот вопрос: Макросы Scala: «не может создать TypeTag из типа T с неразрешенными параметрами типа»Официальный сайт документации Scala также содержит руководство для Reflection .
источник
==
для типов представляет структурное равенство, а не ссылочное равенство.=:=
принимать во внимание эквивалентности типов (даже неочевидные, такие как эквивалентности префиксов, которые поступают из разных зеркал), 2) обаTypeTag
иAbsTypeTag
основаны на зеркалах. Разница в том, чтоTypeTag
допускаются только полностью инстанцированные типы (т.е. без каких-либо параметров типа или ссылок на абстрактные члены типа), 3) Подробное объяснение здесь: stackoverflow.com/questions/12093752Int
и универсальные типы, такие какList[Int]
), оставляя в стороне такие типы Scala, как, например, уточнения, зависимые от пути типы, экзистенциалы, аннотированные типы. Кроме того, манифесты - это болт, поэтому они не могут использовать обширные знания, которые предоставляет компилятор, скажем, для вычисления линеаризации типа, выяснения, является ли один тип подтипами другого, и т. Д.Types.scala
(7kloc кода, который знает, как типы поддерживаются для совместной работы),Symbols.scala
(3kloc кода, который знает, как работают таблицы символов) и т. Д.ClassTag
является точной заменойClassManifest
, тогдаTypeTag
как более или менее заменяетManifest
. Более или менее, потому что: 1) теги типа не несут стирания, 2) манифесты - большой взлом, и мы отказались от эмуляции его поведения с тегами типа. # 1 может быть исправлено с помощью границ контекста ClassTag и TypeTag, когда вам нужны как стирания, так и типы, и обычно не заботятся о # 2, потому что становится возможным отбросить все взломы и использовать полноценный API отражения вместо.