【问题标题】:Is there a way to mark object in Scala as not holding mutable state?有没有办法在 Scala 中将对象标记为不保持可变状态?
【发布时间】:2016-12-12 13:47:51
【问题描述】:

我对 Scala 比较陌生。我有几个辅助方法,需要将它们放在某个地方。我的直觉是将辅助方法分组为无状态 object

但令人担忧的是,我或其他人可能会开始使用 var 字段向该对象添加状态。这将导致副作用,不仅辅助方法的参数而且对象的状态都会影响方法的行为。

我现在想对此进行保护,并且需要将对象标记为不保持(可变)状态,以便编译器或某些验证工具(例如 Fortify)在有人尝试向对象添加状态时引发错误。斯卡拉有可能吗?是否有一些@Immutable@Stateless 注释?

示例代码:

object StreamHelpers /* <-- this needs to be marked immutable or stateless */ {

  var something: String = "change me" // <-- this should cause build to fail

  def streamToString(stream: InputStream): String = {
    managed(new InputStreamReader(stream, StandardCharsets.UTF_8))
      .map(reader => CharStreams.toString(reader)).getTry.get
  }

  // other stuff
}

更新:根据 cmets 中的讨论,我很想知道在 Scala 中是否可以:

  1. 不允许将var-s 添加到object

  1. 不允许将val-s 和var-s 添加到object

带有任何类型的关键字或注释。或者,如果 Scala 不支持开箱即用,是否可以通过宏或元编程来实现?

【问题讨论】:

  • 也许是“val”?我同意@Pavel
  • 你是对的。无用的评论:/对不起:/
  • 也许有一些静态分析工具可以做到这一点,但这不是 StackOverflow 的主题。通常,避免此类错误的方法通常是通过代码审查过程。我看不出您如何完全保护未来开发人员的任何代码。
  • 在您的代码验证工具中简单地将var 标记为错误会更容易。需要时带有特定注释。
  • 你把两个不同的东西混为一谈,我相信这是上面val vs var cmets 的原因。 “不变性”是指对象的状态在创建后不能改变。您所说的是在实施过程中“当有人尝试添加状态时引发错误” - 这是完全不同的事情。我对人们对你的问题感到困惑并不感到惊讶。

标签: scala immutability


【解决方案1】:

使用WartRemover。没有内置检查(除了一个禁止所有使用var的检查),但编写一个应该不难(并且包括可变集合vals,而你是在它)。或者,如果您只想将特定对象标记为不可变,macro annotation 将采用基本相同的代码。

【讨论】:

  • 我最终在 ScalaStyle 检查器中禁止了 var-s,因为已经为项目设置了一个。
猜你喜欢
  • 2021-08-01
  • 1970-01-01
  • 2021-09-29
  • 2016-10-23
  • 1970-01-01
  • 2020-12-05
  • 2021-01-13
  • 2021-02-20
  • 1970-01-01
相关资源
最近更新 更多