Scala函数从泛型中提取Class [_]

时间:2018-11-15 12:30:08

标签: scala scala-reflect

所以我想做什么:

pgroup

对于给定的pgroup,我想查找创建它的类型,因此最后,当运行类型为pgroupid时,我将得到itemmaster。我该怎么做?我必须使用反射吗?

2 个答案:

答案 0 :(得分:1)

简单地说:Class不包含有关类型参数的任何信息。

例如

classOf[Option[Int]] eq classOf[Option[String]]

将返回true。请注意,运算符eq检查引用相等性,因此这两个实际上是完全相同的对象!

Try it out!

即使进行反思,您也将无法获得不存在的信息。


我建议不要使用Class值,而应将类型参数和类型类用于即席多态性。确切的解决方案取决于您有效地尝试做的事情。

但是,这是一个有关类型类如何工作的示例:

def get[F[_], A](a: F[A])(implicit ex: Extractor[A]): Unit = ex.extract

trait Extractor[A] {
  def extract: Unit
}

implicit val intExtractor = new Extractor[Int] {
  def extract: Unit = println("I am doing something for Int!")
}

implicit val strExtractor = new Extractor[String] {
  def extract: Unit = println("I am doing something for String!")
}

val a = Some(1)

get(a)

输出:

I am doing something for Int!

Try it out!

有关更多信息,我建议您阅读The Type Astronaut’s Guide to Shapeless,该书(除了教您有关Shapeless的知识之外)还可以帮助您了解Scala中通用编程的更多常规方面。

我希望这会有所帮助。

答案 1 :(得分:0)

由于类型擦除,您无法从Class获得该信息。为此,您需要使用ClassTag

import scala.reflect.runtime.universe._
def foo[T : TypeTag](clazz: Class[T]) = clazz match {
   ...
   case `opt` => foo(typeOf[T].typeArgs.head)
   ...
}

但是在执行此操作之前,请先检查TypeTypeTag以及scala.reflect.runtime.universe中的其他优点-您很有可能会找到一种更简单,更优雅的实现方式您需要的东西,而不是传递原始的Class