隐式方法参数列表中的Manifest来自哪里?

时间:2013-01-29 09:20:16

标签: scala

我在另一篇文章中尝试了一个例子:How do I get around type erasure on Scala? Or, why can't I get the type parameter of my collections?。以下是可行的例子:

object Registry {
   import scala.reflect.Manifest

   private var map = Map.empty[Any, (Manifest[_], Any)]

   def register[T](name: Any, item: T)(implicit m: Manifest[T]) {
      map = map.updated(name, m -> item)
   }

   def get[T](key: Any)(implicit m: Manifest[T]): Option[T] = {
     map get key flatMap {
      case (om, s) => if (om <:< m) Some(s.asInstanceOf[T]) else None
   }
  }
}

object App extends App {
   Registry.register("a", List(1, 2, 3))

   println(Registry.get[List[Int]]("a"))
   //Some(List(1, 2, 3))
  }

我有两个问题:

  1. 对于方法寄存器,有一个隐式参数m:Manifest [T],我认为应该在某处使用该参数。但是没有定义,为什么它可用?
  2. 这一行:case (om, s) => if (om <:< m) Some(s.asInstanceOf[T]) else None,在方法get中,om <:< m是什么意思?这是我第一次看到这种用法。

1 个答案:

答案 0 :(得分:1)

  1. 编译器插入清单implicits(当它可以生成它们时)。
  2. om <:< m检查清单om所代表的类型是清单m所代表类型的子类型。
  3. 注意:

    • 清单由Scala 2.10中的TypeTags取代
    • 关于清单的<:<方法并不总是准确的(例如,它可以忽略类型参数上的协方差/逆变量注释,IIRC)。