在Scala中是否可以为具有泛型参数的类定义单例?是的是复数,因为泛型参数的每个实例必须有一个单例。在一般情况下,这是无稽之谈,我相信,但如果泛型参数是特定事物的子类型,我想知道它是否可行。
作为一个例子,将所有泛型参数的特定超类型视为此抽象类。
abstract class BaseType[T<:BaseType] {
val omega:T;
}
这个想法是每个实现都有一个特殊的值,这是欧米茄。现在我想要一个具有BaseType
子类型作为通用参数的类:
class Thing[T<:BaseType[T]](val v:T, foo:Int);
由于每个T
都具有特定值omega
,因此我希望Thing
包含omega
,例如foo=0
的单身人士。我甚至做不到
object Thing {
def OmegaInstance[T<:BaseType[T]] = new Thing(/*what gos here?*/, 0);
}
但即使我可以,OmegaInstance对于每次通话都是新的,我不想要。
有机会让这个工作吗?
答案 0 :(得分:0)
如果您的输入类型参数未被删除,您可以实现相同的旧轻量级模式,但使用TypeTag
作为键:
import scala.reflect.runtime.universe._
import scala.collection.concurrent._
object Things {
class Thing[T] private[Things]() { //private constructor, class itself is still accessable
//...
}
private val map = TrieMap[TypeTag[_], Thing[_]]()
def Thing[T: TypeTag] =
map.getOrElseUpdate(typeTag[T], new Thing[T]).asInstanceOf[Thing[T]] //`asInstanceOf` is safe here
}
用法示例:
import Things._
scala> Thing[Int]
res2: Things.Thing[Int] = Things$Thing@4472abe8 //new object
scala> Thing[Int]
res3: Things.Thing[Int] = Things$Thing@4472abe8 //same object
scala> Thing[Int]
res4: Things.Thing[Int] = Things$Thing@4472abe8 //same object
scala> Thing[String]
res5: Things.Thing[String] = Things$Thing@4745c8d2 //new object
scala> Thing[String]
res6: Things.Thing[String] = Things$Thing@4745c8d2 //same object
您可以在此处使用任何参数实例化您想要的任何内容。用法看起来几乎就像只有泛型参数化object
(每个通用的一个单例)。