【问题标题】:Lazy Singleton in ScalaScala 中的懒惰单例
【发布时间】:2013-08-08 02:26:43
【问题描述】:

随着我对 Scala 的不断学习,我对 Scala 语言中的一些选择很感兴趣。考虑删除静态类。在 Java 世界中(我来自哪里),静态成员、单例成员和实例成员之间存在明显区别。 Java 中始终存在对单例的持续需求,而静态成员无法真正提供帮助。我知道为什么单例可能优于静态成员的主要用例是:

  1. 能够控制单例对象的实例化。如果加载一个类的实例会占用大量资源,我们希望稍后再将其推迟到真正需要它为止。
  2. 能够在运行时配置单例对象。想象一下在构建时必须读取环境变量并填充我们的单例。如果成员是静态的,则无法做到这一点,因为在类加载时可能不知道该信息。

然而,Scala 的单例实现似乎没有上述好处。看这里的讨论:http://pbadenski.blogspot.com/2009/06/design-patterns-in-scala-singleton.html

在我看来, Scala 根本没有解决单例用例。这将是令人失望的。

如果我的理解是正确的,那么下一个问题是:我们如何在 Scala 中启用惰性单例模式?

似乎我们必须与 scala 斗争才能以正确的方式获得单例!

PS:这不是我的博客

【问题讨论】:

  • 什么是“又是单例问题?”
  • 此外,我自 2008 年以来一直在使用 Scala,并且不记得 objects 的实例化是在类加载期间。
  • 我喜欢你的问题(它得出了一些很好的答案)但我不会投票,因为 - 正如所写 - 它试图回答自己,我不同意你的结论。
  • 另请注意,Scala“类的静态部分”是单例“对象”。这是一个真正的对象:你可以引用它,它可以继承特征/接口......所以如果你想从某个工厂“不同”实现,工厂当然可以返回对不同“对象”的引用。
  • 博文中这个问题的陈述是错误的。

标签: scala scala-2.10


【解决方案1】:

Scala 中的单例是懒惰的。在您的 REPL 中尝试以下操作:

scala> object Foo { println("hello") }
defined module Foo

scala> 1+1
res0: Int = 2

scala> Foo
hello
res1: Foo.type = Foo$@37c8ccf4

scala> Foo
res2: Foo.type = Foo$@37c8ccf4

从 println 中可以看出,Foo 在使用之前不会被初始化。

【讨论】:

    【解决方案2】:

    TOUR OF SCALA SINGLETON OBJECTS

    对象是一个只有一个实例的类。它在被引用时是惰性创建的,就像一个惰性 val。

    作为封闭类的成员或本地值,它的行为与惰性 val 完全相同。

    下面是演示

    scala> object Foo { println("hello") }
    defined object Foo
    
    scala> val f = Foo
    hello
    f: Foo.type = Foo$@2e26173
    

    scala> object Foo { println("hello") }
    defined object Foo
    
    scala> lazy val f = Foo
    f: Foo.type = <lazy>
    
    scala> f
    hello
    res0: Foo.type = Foo$@7bf018dd
    

    【讨论】:

      猜你喜欢
      • 2012-11-04
      • 1970-01-01
      • 1970-01-01
      • 2017-01-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-20
      • 2016-07-24
      相关资源
      最近更新 更多