1

I want to get actual type class from Generic type.

When I try this

I get class scala.runtime.Nothing only.

import scala.reflect._

class Car {

}

object Car extends Model[Car] {

}

trait Model[T] {

  def something[T:ClassTag]():Unit = {
    println(classTag[T].runtimeClass)
  }

}

Car.something() // <- scala.runtime.Nothing$
Michael Zajac
  • 55,144
  • 7
  • 113
  • 138
Scalalang2
  • 536
  • 1
  • 7
  • 19

3 Answers3

3

You might want something like the following: The T=:=U would unify the two types and the :ClassTag would just create a ClassTag for it.

Edit: the correct, but still too complicated form:

trait Model[T] {
  def something[U](implicit ev: T =:= U, tag: ClassTag[U]): Unit = {
    println(tag.runtimeClass)
  }

In general, I would also use https://stackoverflow.com/a/27666845/1502148 (when I am not sleepy :) ).

Community
  • 1
  • 1
Gábor Bakos
  • 8,982
  • 52
  • 35
  • 52
  • This is 1) not a legal syntax; 2) more complicated than required if you fix the syntax to `def something[U](implicit ev: T =:= U, tag: ClassTag[U])`. – Alexey Romanov Dec 27 '14 at 11:40
2
class Model[T:ClassTag] {

  def something():Unit = {
    println(classTag[T].runtimeClass)
  }

}

I solved by modifying Model trait to class and provide ClassTag to Generic.

Scalalang2
  • 536
  • 1
  • 7
  • 19
1

If you want to allow creating a Model without ClassTag and only require ClassTag for some methods, you can do

trait Model[T] {
  def something(implicit tag: ClassTag[T]):Unit = ...
}

Obviously this applies to e.g. Numeric, Ordering, etc. constraints as well.

Alexey Romanov
  • 167,066
  • 35
  • 309
  • 487