具有通用参数的类的多个单身人士

时间:2014-09-27 16:17:43

标签: scala generics singleton

在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对于每次通话都是新的,我不想要。

有机会让这个工作吗?

1 个答案:

答案 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(每个通用的一个单例)。