作为单身人士的特质

Trait as Singleton

是否可以让 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() 函数所暗示的想法相同,该函数将检索元素的现有实例(如果元素已经存在)或创建它。

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

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.

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

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