Scala 具有泛型参数的类的复数单例

Scala 具有泛型参数的类的复数单例,scala,generics,singleton,Scala,Generics,Singleton,在Scala中,是否可以使用泛型参数为类定义单例?是的,它是复数形式,因为泛型参数的每个实例都必须有一个单例。我相信,在最一般的情况下,这是胡说八道,但如果泛型参数是某个特定对象的子类型,我想知道它是否可行 作为一个例子,将所有泛型参数的特定超类型视为这个抽象类。 abstract class BaseType[T<:BaseType] { val omega:T; } 因为每个T都有特定的值omega,所以我希望Thing包含omega的单例,比如说,foo=0。我甚至做不到 ob

在Scala中,是否可以使用泛型参数为类定义单例?是的,它是复数形式,因为泛型参数的每个实例都必须有一个单例。我相信,在最一般的情况下,这是胡说八道,但如果泛型参数是某个特定对象的子类型,我想知道它是否可行

作为一个例子,将所有泛型参数的特定超类型视为这个抽象类。

abstract class BaseType[T<:BaseType] {
  val omega:T;
}
因为每个
T
都有特定的值
omega
,所以我希望
Thing
包含
omega
的单例,比如说,
foo=0
。我甚至做不到

object Thing {
  def OmegaInstance[T<:BaseType[T]] = new Thing(/*what gos here?*/, 0);
}
对象对象对象{

def OmegaInstance[T如果输入类型参数未被擦除,则可以实现相同的旧轻量级模式,但将
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

你可以在这里用任何参数实例化你想要的任何东西。这种用法看起来就像是让泛型参数化的
对象
(每个泛型对应一个单例).

您肯定需要Tcl的实例,这将是Java的方式。考虑到所有漂亮的类型技巧,我想知道Scala是否可以在这里创造一个奇迹。在这种情况下,您应该有一些隐式的
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