【问题标题】:methods with state Groovy / Java具有状态 Groovy / Java 的方法
【发布时间】:2021-02-16 05:54:57
【问题描述】:

我有一个冗长的问题。假设我有一个进行数学计算的方法,并且该方法需要保持状态(即,每次使用参数调用它时,其结果都会受到其先前结果的影响)。

int sum

def add(int x, int y) {
 sum = sum + x + y
 return sum
}

最重要的是,它的状态取决于它被调用的位置。 (即,如果我从不同的地方两次调用此方法,则该方法必须仅适用于其自己的状态)。我在考虑 groovy 中的闭包,但闭包不会保持状态,如果您将状态存储在闭包外部的变量中,则对该方法的第二次调用将不会有自己的状态。

我们还假设由于我现在不会讨论的原因,我不能将此方法保留在对象中以保持状态。即

class MyObject {
   private int sum

   MyObject() {}

   public int sum(int x, int y) {
     sum = sum + x + y
     return sum
  }
}

我想避免这样做

MyObject mObj = new MyObject()
.... some code later
def result = mObj.add(1,2)

相反,我只想这样做

for (int i = 0; i<5;i++){
    def result1 = add(1,2)
}
some code later
for (int i = 0; i<5;i++){
    def result2 = add(1,2)
}

在上述情况下,两个 'add' 方法应该有自己的状态。

在 groovy 或 java 中是否有任何其他技巧可以实现这样的目标?

【问题讨论】:

  • “由于我现在不会进入的原因,我不能将此方法保留在对象中以保持状态”:好吧,出于我现在不会进入的原因,你不会得到一个令人满意的答案。

标签: java groovy


【解决方案1】:

你在这里描述的是一个闭包。那里的 Groovy 代码 已经这样了。如果您想将该“全局”状态放入函数中,您 可以明确说明并“构建”add 函数。例如

def add = { ->
    def total = 0
    return { a, b -> 
        return total += a + b 
    }
}()

println(add(1,2))
// -> 3
println(add(1,2))
// -> 6
println(add(1,2))
// -> 9

上面的代码创建了一个函数,它保存total 的状态和 返回一个闭包,它执行实际的添加。它捕捉本地 total。然后调用这个函数,结果(闭包)是 分配给add

编辑

正如 cmets 中所述,期望是一个“魔法”边界, 在执行过程中隔离add 的状态 程序。假设这个问题是针对 DSL 的,用户可能是 能够知道隐含的边界。然而我怀疑有没有办法 Groovy(或 Java?)要知道,从内部调用函数 一个 for 循环,除非你自己写 for。

解决这个问题的一种方法是创建一个明确的边界,如下所示:

def withTotal(c) {
    def total = 0
    c.add = { total += it }
    c.call()
    total
}

println withTotal{
    add(1)
    add(2)
}
// -> 3

println withTotal{
    10.times{ add it }
}
// -> 45

【讨论】:

  • 至少对我来说,很清楚,您希望最后一个示例中的 add() 给出相同的结果,因此我认为您可以通过在您的示例中添加 cmets,您期望得到什么结果。另外,如果在some code later 级别调用它应该如何添加工作?如果您想在随机点引入新状态,您需要标记 - groovy/java 不会神奇地知道,现在代码在 for 循环中被调用。
  • 如果您在第二个 for 之前再次调用该构建器,这将如您所愿。每次调用都会为您提供一个新的总数,这就是当时创建的闭包的状态,因为它只被该闭包捕获,其他人没有。
  • 是否有可能有类似上面的东西,但有一个 for 循环 for (int i = 0; i
猜你喜欢
  • 2011-02-03
  • 2016-08-11
  • 2019-07-16
  • 2013-08-28
  • 2019-01-04
  • 2011-02-19
  • 2012-10-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多