如何从scala中的多态类型创建对象属性
我试图创建一个对象来存储该对象创建的实例,并避免重新加载。我试图在对象上创建一个可变映射来存储它,但是我得到了一个编译错误 这是我的代码:如何从scala中的多态类型创建对象属性,scala,Scala,我试图创建一个对象来存储该对象创建的实例,并避免重新加载。我试图在对象上创建一个可变映射来存储它,但是我得到了一个编译错误 这是我的代码: class Bar class FooBar extends Bar object Foo { val loaded = scala.collection.mutable.Map[String, Bar]() def apply[T <: Bar](implicit m: Manifest[T]): T = { v
class Bar
class FooBar extends Bar
object Foo {
val loaded = scala.collection.mutable.Map[String, Bar]()
def apply[T <: Bar](implicit m: Manifest[T]): T = {
val className = m.toString()
if (loaded.contains(className)) {
return loaded(className)
}
val instance = m.runtimeClass.newInstance().asInstanceOf[T]
loaded(className) = instance
instance
}
}
还有另一种方法可以动态创建地图并传递T?或者以不同的方式解决此问题?您的问题在于返回的是
已加载(className)
,其类型为Bar
,而不是函数类型签名所要求的T
。不幸的是,您无法编码映射键和值类型之间的这种依赖关系,至少不能使用标准映射集合。您必须执行显式强制转换。以下是一个工作示例:
import scala.reflect.ClassTag
class Bar
class FooBar extends Bar
object Test {
val classMap = scala.collection.mutable.Map[Class[_], Bar]()
def getInstance[T <: Bar : ClassTag]: T = {
val ct = implicitly[ClassTag[T]]
classMap get ct.runtimeClass match {
case Some(bar) => bar.asInstanceOf[T]
case None =>
val instance = ct.runtimeClass.newInstance().asInstanceOf[T]
classMap(ct.runtimeClass) = instance
instance
}
}
}
object Main {
def main(args: Array[String]) {
println(Test.getInstance[FooBar])
println(Test.getInstance[Bar])
println(Test.getInstance[FooBar])
}
}
第二,最好的是:
import scala.reflect.ClassTag
class Bar
class FooBar extends Bar
object Test {
val classMap = scala.collection.mutable.Map[Class[_], Bar]()
def getInstance[T <: Bar : ClassTag]: T = {
val ct = implicitly[ClassTag[T]]
classMap.getOrElseUpdate(ct.runtimeClass, ct.runtimeClass.newInstance().asInstanceOf[Bar]).asInstanceOf[T]
}
}
object Main {
def main(args: Array[String]) {
println(Test.getInstance[FooBar])
println(Test.getInstance[Bar])
println(Test.getInstance[FooBar])
}
}
导入scala.reflect.ClassTag
分类栏
类FooBar扩展了Bar
对象测试{
val classMap=scala.collection.mutable.Map[Class[\ux],Bar]()
def getInstance[T您可以使用case-Some(bar:T)=>bar
,由于类标记的原因,我认为它匹配得很好。您还可以(也许更好)使用getOrElseUpdate
@0\u,是的,您是对的。每天我都在学习有关Scala标准库的新知识)
import scala.reflect.ClassTag
class Bar
class FooBar extends Bar
object Test {
val classMap = scala.collection.mutable.Map[Class[_], Bar]()
def getInstance[T <: Bar : ClassTag]: T = {
val ct = implicitly[ClassTag[T]]
classMap get ct.runtimeClass match {
case Some(bar: T) => bar
case None =>
val instance = ct.runtimeClass.newInstance().asInstanceOf[T]
classMap(ct.runtimeClass) = instance
instance
}
}
}
object Main {
def main(args: Array[String]) {
println(Test.getInstance[FooBar])
println(Test.getInstance[Bar])
println(Test.getInstance[FooBar])
}
}
import scala.reflect.ClassTag
class Bar
class FooBar extends Bar
object Test {
val classMap = scala.collection.mutable.Map[Class[_], Bar]()
def getInstance[T <: Bar : ClassTag]: T = {
val ct = implicitly[ClassTag[T]]
classMap.getOrElseUpdate(ct.runtimeClass, ct.runtimeClass.newInstance().asInstanceOf[Bar]).asInstanceOf[T]
}
}
object Main {
def main(args: Array[String]) {
println(Test.getInstance[FooBar])
println(Test.getInstance[Bar])
println(Test.getInstance[FooBar])
}
}