Scala 如何使用参数化类作为键操纵贴图

Scala 如何使用参数化类作为键操纵贴图,scala,types,implicit,f-bounded-polymorphism,classtag,Scala,Types,Implicit,F Bounded Polymorphism,Classtag,我试图定义一个以参数化类为键的映射。但当我尝试添加到它时,我得到一个编译器错误: trait MyTrait[T <: MyTrait[T]] case class A(i: Int) extends MyTrait[A] case class B(str: String) extends MyTrait[B] var map = Map[Class[_ <: MyTrait[_]], Int]() def update[T <: MyTrait[T]](n: Int)

我试图定义一个以参数化类为键的映射。但当我尝试添加到它时,我得到一个编译器错误:

trait MyTrait[T <: MyTrait[T]]

case class A(i: Int) extends MyTrait[A]
case class B(str: String) extends MyTrait[B]

var map = Map[Class[_ <: MyTrait[_]], Int]()

def update[T <: MyTrait[T]](n: Int) = {
    map += classOf[T] -> n  // Won't compile
}
  Expression does not convert to assignment because:  
    class type required but T found  
    expansion: map = map.+(classOf[T].<$minus$greater: error>(n))  
        map += classOf[T] -> n  

您应该添加上下文绑定的
ClassTag
,并将
classOf[T]
替换为
ClassTag[T].runtimeClass

classOf[T]
与实际类(现在已知的类,如
classOf[Int]
classOf[String]
等)一起使用。对于类型参数(调用方法时将成为类类型),您需要类标记

def update[T <: MyTrait[T]: ClassTag](n: Int) = {
  val clazz = classTag[T].runtimeClass.asInstanceOf[Class[T]]
  map += clazz -> n
}

println(map) //HashMap()
update[A](1) 
println(map) //HashMap(class A -> 1)
update[B](2)
println(map) //HashMap(class A -> 1, class B -> 2)
def更新[T n
}
println(map)//HashMap()
更新[A](1)
println(map)//HashMap(类A->1)
更新[B](2)
println(map)//HashMap(类A->1,类B->2)

要使
classOf
与泛型一起工作,您必须指定希望在运行时具有类型信息。通常您需要一些
ClassTag
魔术。这里的问题是
T
是一个
类型,而不是一个类,因此
classOf
将不起作用。您需要使用re来提取类型的类对我来说,像F-Bound多态性、可变映射和想要使用类作为键等都是代码的味道。我可以问一下你想解决的元问题是什么吗?
def update[T <: MyTrait[T]: ClassTag](n: Int) = {
  val clazz = classTag[T].runtimeClass.asInstanceOf[Class[T]]
  map += clazz -> n
}

println(map) //HashMap()
update[A](1) 
println(map) //HashMap(class A -> 1)
update[B](2)
println(map) //HashMap(class A -> 1, class B -> 2)