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