Как получить обобщенное c простое имя класса из scala TypeTag? - PullRequest
1 голос
/ 17 марта 2020

Как я могу получить простое имя класса, включая generi c, используя TypeTag? Я думаю, что подпись метода должна выглядеть следующим образом:

def getClassName[A: TypeTag](a: A): String

getClassName(Map("a" -> 123)) должен возвращать Map[String,Int].


То, что я пробовал:

def getClassName[A: TypeTag](a: A): String = {
  typeOf[A].typeSymbol.name.toString
}

scala> getClassName(Map("a" -> 123))
res1: String = Map
def getClassName[A: TypeTag](a: A): String = {
  typeOf[A].typeSymbol.toString
}

scala> getClassName(Map("a" -> 123))
res1: String = trait Map
def getClassName[A: TypeTag](a: A): String = {
  typeOf[A].toString
}

scala> getClassName(Map("a" -> 123))
res1: String = scala.collection.immutable.Map[String,Int] // It knows the full type!
def getClassName[A: TypeTag](a: A): String = {
  typeOf[A].typeSymbol.fullName
}

scala> getClassName(Map("a" -> 123))
res1: String = scala.collection.immutable.Map

Ответы [ 2 ]

1 голос
/ 17 марта 2020

Отсюда: https://docs.scala-lang.org/overviews/reflection/typetags-manifests.html

import scala.reflect.runtime.universe._

def getClassName[T](x: T)(implicit tag: TypeTag[T]): String = {
    tag.tpe match { case TypeRef(_, t, args) => s"""${t.name} [${args.mkString(",")}]""" }
}

getClassName(Map("a" -> 123))

res5: String = Map [java.lang.String,Int]

ОБНОВЛЕНИЕ: более короткая версия с полными именами классов

 def getClassName[T: TypeTag](x: T) = typeOf[T].toString

getClassName(Map("a" -> 123))
res1: String = scala.collection.immutable.Map[java.lang.String,Int]
0 голосов
/ 18 марта 2020

Я добавлю свои ответы на этот вопрос, основываясь на ответе Артема Алиева , поскольку не похоже, что Scala имеет эту встроенную функцию. Этот метод использует контекстный синтаксис вместо неявного параметра.

def getClassName[A: TypeTag](a: A): String = {
  val typeArgs = typeOf[A].typeArgs
  s"${typeOf[A].typeSymbol.name}${if (typeArgs.nonEmpty) typeArgs.mkString("[",",", "]") else ""}"
}
scala> getClassName(Map("a" -> 123))
res1: String = Map[String,Int]
...