1

我尝试了另一篇文章中的一个示例:如何在 Scala 上解决类型擦除问题?或者,为什么我不能获取我的集合的类型参数?. 以下是可行的示例:

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] for method register,我认为这个参数应该定义在某个地方使用。但是没有定义,为什么有用呢?
  2. 这一行:case (om, s) => if (om <:< m) Some(s.asInstanceOf[T]) else None,在方法get中,是什么om <:< m意思?这是我第一次看到这样的用法。
4

1 回答 1

1
  1. 清单隐含由编译器插入(当它可以生成它们时)。
  2. om <:< m检查 manifest 表示的类型是否是 manifest 表示om的类型的子类型m

笔记:

  • 清单在 Scala 2.10 中被 TypeTags 取代
  • Manifests 上的<:<方法并不总是准确的(例如,它可以忽略类型参数上的协变/逆变注释,IIRC)。
于 2013-01-29T10:12:59.097 回答