特质作为辛格尔顿

时间:2019-07-10 13:27:48

标签: scala singleton traits

是否可以让trait成为singleton

我想要实现的是拥有一个干净轻巧的API,我可以像下面这样扩展整个应用程序:

trait SingletonTrait {
  // element I wish to be unique throughout my application
  val singletonElement = ///

  ...
}

// uses *singletonElement*
object MainApplication extends SingletonTrait {
  ...
}

// uses *singletonElement*
class SomeClass(...) extends SingletonTrait {
  ...
}

getOrCreate()函数所隐含的相同思想中,如果一个元素已经存在,则该元素将检索该元素的现有实例,否则将创建该元素。

2 个答案:

答案 0 :(得分:5)

也许只是在伴侣对象中创建值并在特征中引用它?

trait SingletonTrait {
  final lazy val singletonElement = SingletonTrait.SingletonElement
}

object SingletonTrait {
  lazy val SingletonElement = {
    println("Creating singleton element!")
    "singleton element"
  }
}

// uses *singletonElement*
class SomeClass() extends SingletonTrait {
    println(s"Using ${singletonElement} in class.")
}

new SomeClass()
new SomeClass()
new SomeClass()

它打印:

Creating singleton element!
Using singleton element in class.
Using singleton element in class.
Using singleton element in class.

答案 1 :(得分:3)

从技术上讲,您可以这样做

object SingletonElement {
  var count = 0
}

trait SingletonTrait {
  final val singletonElement = SingletonElement
}

object MainApplication extends SingletonTrait {
  singletonElement.count = singletonElement.count + 1
}

class SomeClass extends SingletonTrait {
  singletonElement.count = singletonElement.count + 1
}

我们可以测试是否使用了相同的对象

new SomeClass
MainApplication
SingletonElement.count

应输出

res2: Int = 2

其中显示了使用相同的SingletonElement