Я хотел бы получить имя типа, как String, без отражения во время выполнения.Scala: Получить имя типа без отражения во время выполнения и без экземпляра типа
Использование макросов и с экземпляром типа, я могу сделать это так:
def typeNameFromInstance[A](instance: A): String =
macro typeNameFromInstanceImplementation[A]
def typeNameFromInstanceImplementation[A](
c: Context)(
instance: c.Expr[A]): c.Expr[String] = {
import c.universe._
val name = instance.actualType.toString
c.Expr[String](Literal(Constant(name)))
}
Как я могу сделать это без экземпляра типа? Я хотел бы сигнатуру функции, как:
def typeName[A]: String
Я не могу использовать ClassTags, потому что они не обеспечивают полное имя типа, просто стертый тип. Я также, видимо, не могу использовать TypeTags из-за thread safety issues.
EDIT: Похоже, что это невозможно в полной общности (например, вложенные вызовы функций). В принятом ответе ниже говорится об этом в комментариях.
Это решение не возвращает конечный статический тип. Предположим, что я определяю: «def printType [A] = println (typeName [A])». Затем вызов «printType [List [Int]]» печатает «A» не «Список [Int]». – emchristiansen
Если вы хотите, чтобы это работало так, я не думаю, что это возможно без 'TypeTag'. Макрос расширяется во время компиляции, поэтому ваш код: 'def printType [A] = println (typeName [A])' фактически переводится в 'def printType [A] = println (" A ")'. Единственное, что вы можете здесь сделать, это определить 'printType' также как макрос. Его реализация может выглядеть так: 'def printType_impl [T] (c: Context): c.Expr [Unit] = c.universe.reify (println (typeName_impl [T] (c) .splice))' – ghik