映射List [Class [_&lt ;: X]]以获取List [Foo [A]]

时间:2015-02-21 03:37:56

标签: scala

考虑以下类型:

scala> trait Parent
defined trait Parent

scala> case class Girl extends Parent
defined class Girl

scala> case class Boy extends Parent
defined class Boy

然后是List[Class[_ <: Parent]]

scala> List[Class[_ <: Parent]](Boy().getClass, Girl().getClass)
res18: List[Class[_ <: Parent]] = List(class Boy, class Girl)

然后,我定义了一个类Blah,它接受​​一个Parent子元素的类型参数。它有一个隐式Manifest[A]和一个方法。

scala> class Blah[A <: Parent](implicit m: scala.reflect.Manifest[A]) { 
       |     def getRuntimeClass = m.runtimeClass 
       |} 
defined class Blah

为什么我map无法List[Class[_ <: Parent]]获得List[Blah[A]]

scala> res18.map(x => new Blah[x.type])
<console>:15: error: type arguments [x.type] do not conform to class Blah's type parameter bounds [A <: Parent]
              res18.map(x => new Blah[x.type])
                                 ^

修改

我可以这样做:

scala> res18.map(_ => new Blah)
res20: List[Blah[Nothing]] = List(Blah@5de6af79, Blah@540a6118)

然后我得到Nothing作为类型,这是有道理的。这个结果是不可接受的。

scala> res20(0)
res21: Blah[Nothing] = Blah@5de6af79

scala> res21.getRuntimeClass
res22: Class[_] = class scala.runtime.Nothing$

1 个答案:

答案 0 :(得分:2)

您的代码存在的问题是您存储了一个类列表,但需要一个清单列表。

trait Parent
case class Girl() extends Parent
case class Boy() extends Parent

val l = List(manifest[Girl], manifest[Boy])

class Blah[A <: Parent](implicit m: scala.reflect.Manifest[A]) { 
   def getRuntimeClass = m.runtimeClass 
} 

然后你可以使用manifest作为隐式参数,编译器会推断出正确的东西

import scala.reflect._
val res = l.map {
    implicit m =>
    new Blah()
}
res(0).getRuntimeClass

产量

Class[_] = class Girl