How do I get a generic runtime class in Scala?

import scala.reflect.runtime.universe._
import scala.reflect.ClassTag
import scala.reflect.classTag

def getTypeTag[T: TypeTag](obj: T) = println(typeTag[T].tpe)

class Entity
{
    def greet = println("Hello!")
}

class Point[T : TypeTag](val x : T, val y :T) extends Entity

val p = new Point[Int](2,5)
val p2 = new Point[Float](1.0f,-5.0f)
val p3 = new Point[Double](4.0,-7.0)

val path = Array[Entity](p,p2,p3)

path.foreach(getTypeTag(_))

      

This small piece of code writes to stdout

Helper.this.Entity
Helper.this.Entity
Helper.this.Entity

      

I would like to write

Helper.this.Point[Int]
Helper.this.Point[Float]
Helper.this.Point[Double]

      

I know there are many questions about scala reflection, I have read a lot of them but still don't understand the difference between TypeTag, Manifest and ClassTag; and I cannot get this most basic example to work. Any help would be greatly appreciated.

Thank you in advance

+3


source to share


1 answer


Short, sane answer:

You can not. Do not do this. Why do you need this? You are probably wrong ...

Unsatisfactory answer:

def printType(a: Any) =
  a match {
    case p: Point[_] =>
      val clazz = p.getClass.getName
      val tname = p.x.getClass.getName
      println(s"$clazz[$tname]")
    case _ =>
      println("yolo")
  }

class Entity 

class Point[T](val x: T, val y: T) extends Entity

val p = new Point[Int](2,5)
val p2 = new Point[Float](1.0f,-5.0f)
val p3 = new Point[Double](4.0,-7.0)

val path = Array[Entity](p, p2, p3)

path.foreach(printType)

      



Actual answer:

Use Shapeless Typeable .

import shapeless._

val path = p :: p2 :: p3 :: HNil

object printType extends Poly1 {
  implicit def case0[T](implicit t: Typeable[T]) =
    at[T](_ => t.describe)
}

path.map(printType).toList.foreach(println)

      

+1


source







All Articles