状态为Groovy/Java的方法

状态为Groovy/Java的方法,java,groovy,Java,Groovy,我有一个冗长的问题。假设我有一个进行数学计算的方法,这个方法需要保持状态(即,每次使用参数调用它时,它的结果都会受到以前结果的影响) 除此之外,它的状态取决于调用它的位置。(即,如果我从不同的位置调用此方法两次,则该方法只能在其自身状态下工作)。我在考虑groovy中的闭包,但是闭包不保持状态,如果将状态存储在闭包外部的变量中,则对该方法的第二次调用将不会有自己的状态 让我们也假设由于我现在不想讨论的原因,我无法将此方法保留在要保留状态的对象中。i、 e class MyObject {

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

除此之外,它的状态取决于调用它的位置。(即,如果我从不同的位置调用此方法两次,则该方法只能在其自身状态下工作)。我在考虑groovy中的闭包,但是闭包不保持状态,如果将状态存储在闭包外部的变量中,则对该方法的第二次调用将不会有自己的状态

让我们也假设由于我现在不想讨论的原因,我无法将此方法保留在要保留状态的对象中。i、 e

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)
}

for(inti=0;i您在这里描述的是一个闭包
如果你想把“全局”状态放到函数中,你可以
可以明确说明,并“构建”添加功能

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
的状态 假设这个问题是针对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

“由于我现在不想讨论的原因,我无法将此方法保留在要保留状态的对象中”:嗯,由于我现在不想讨论的原因,你的问题不会得到令人满意的答案。是的,这是我开始的,他们可以保持状态,但是,根据最初的问题:除此之外,它的状态取决于它被调用的位置。(也就是说,如果我从不同的地方调用这个方法两次,那么这个方法必须只处理自己的状态)。我在groovy中考虑过闭包,但是闭包不保持状态,如果你将状态存储在闭包之外的变量中,那么对这个方法的第二次调用就不会有自己的状态。至少对我来说,不清楚你是否希望添加()在最后一个示例中,为了得到相同的结果,我认为您可以通过在示例中添加注释来说明这一点,即您期望的结果。如果以后在
某个代码级别调用它,那么应该如何添加工作呢?如果您想在随机点引入新状态,则需要标记-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