2014-09-27 26 views
1

是否有可能在Scala中为具有通用参数的类定义单身人士?是的,它是复数,因为对于泛型参数的每个实例必须有一个单例。我相信在最一般的情况下这是无稽之谈,但如果泛型参数是特定事物的子类型,我想知道它是否可行。具有通用参数的类的多个单身人士

作为一个例子,考虑所有泛型参数的具体超类型是这个抽象类。

abstract class BaseType[T<:BaseType] { 
    val omega:T; 
} 

这个想法是,每个实现都有一个特殊的值,这就是欧米茄。现在,我想其中有BaseType亚型作为通用参数类:

class Thing[T<:BaseType[T]](val v:T, foo:Int); 

因为每个T具有特定值omega,我想有单身含有omegaThing,并说,foo=0。我什至不能做

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

但即使我可以,OmegaInstance将是每个电话,这是我不想要的新的。

有没有机会使此工作?

+0

您肯定需要T <:BaseType [T]的实例来传入Thing的构造函数 – 2014-09-27 16:34:15

+0

显然,这将是Java的方式。鉴于所有漂亮的类型技巧,我想知道斯卡拉是否可以在这里做一个小小的奇迹。 – Harald 2014-09-27 16:36:51

+0

在这种情况下,你应该有一些隐含的提供T <:BaseType [T] – 2014-09-27 16:48:28

回答

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] = [email protected] //new object 

scala> Thing[Int] 
res3: Things.Thing[Int] = [email protected] //same object 

scala> Thing[Int] 
res4: Things.Thing[Int] = [email protected] //same object 

scala> Thing[String] 
res5: Things.Thing[String] = [email protected] //new object 

scala> Thing[String] 
res6: Things.Thing[String] = [email protected] //same object 

可以实例的任何事情,你想在这里有任何参数。用法看起来几乎就像是通用参数化的object(每个通用的一个单例)。