scala - 使用可为空而不是选项?

标签 scala

我有单例:

class MySing private (var1: SomeType) { ... }
object MySing {

  @volatile
  private var instance: Option[MySing] = None

  def apply(var1: SomeType): Option[MySing] = {
    if (instance.isEmpty) {
      this.synchronized {
        if (instance.isEmpty) instance = Some(new MySing(var1))
      }
    }

    instance
  }
}

所以每当我想获取它的实例时,我必须使用 get 或模式匹配

MySing(myVar1) match {
  case Some(x) => ...
  case None =>
}

MySing(myVar1).get

即使 Scala 也鼓励使用 Option,但在我的情况下,不使用它来摆脱上面所示的无聊、冗余的操作不是合理的吗?

object MySing {

  @volatile
  private var instance: MySing = null

  def apply(var1: SomeType): MySing = {
    if (instance == null) {
      this.synchronized {
        if (instance == null) instance = new MySing(var1)
      }
    }

    instance
  }
}

最佳答案

返回Option[MySing]意味着您可能不会从apply返回值(即返回None),但我不这样做看看这有什么意义。您总是从 apply 返回一个实例,因此您可以使用返回类型中的 Option ,如下所示

class MySing private (val var1: String)
object MySing {

  @volatile
  private var instance: Option[MySing] = None

  def apply(var1: String): MySing = {
    instance getOrElse {
      this.synchronized {
        instance.getOrElse {
         instance = Some(new MySing(var1))
         instance.get
        }
      }
    }
  }
}

使用示例

scala> val x = MySing("hello")
x: MySing = MySing@232b0a52

scala> x.var1
res0: String = hello

scala> val y = MySing("hola")
y: MySing = MySing@232b0a52

scala> y.var1
res1: String = hello // are you sure this is sensible?

但是,它看起来仍然有点难看:您正在创建一个带有参数的单例,因此忽略了第一次调用后传递给 apply 方法的每个参数。呃!

您可能想要重新考虑您的设计(并忘记 null)

关于scala - 使用可为空而不是选项?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25168908/

相关文章:

mysql - 使用 Anorm 确保查询是否执行

scala - 将无形的可扩展记录传递给函数(永无止境的故事?

scala - 可以在 spark 中处理多字符分隔符

Scala:以简单的自定义类型实现 map 和 withFilter

scala - 如何在需要 @XmlJavaTypeAdapter 时使用 JAXB/SCALA(反)序列化对象?

scala - 如何在也只接受子类的 Scala 中进行结构类型化?

Scala 项目组织

scala 多 sbt 项目 : object is not a member of package, 未找到类型

scala - 启用 csrf.sign.tokens 时,Play 2.2.1 Scala 中的 CSRF 总是失败

sql - 带动态最后的 Spark 高级窗口