java - 具有状态 Groovy / Java 的方法
问题描述
我有一个冗长的问题。假设我有一个进行数学计算的方法,并且该方法需要保持状态(即,每次使用参数调用它时,其结果都会受到其先前结果的影响)。
int sum
def add(int x, int y) {
sum = sum + x + y
return sum
}
最重要的是,它的状态取决于它被调用的位置。(即,如果我从不同的地方两次调用此方法,则该方法必须仅适用于它自己的状态)。我在考虑 groovy 中的闭包,但闭包不会保持状态,如果您将状态存储在闭包之外的变量中,则对该方法的第二次调用将不会有自己的状态。
让我们还假设由于我现在不会进入的原因,我不能将此方法保留在对象中以保持状态。IE
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)
}
在上述情况下,两个“添加”方法应该有自己的状态。
groovy 或 java 中是否还有其他技巧可以实现这样的目标?
解决方案
你在这里描述的是一个闭包。那里的 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
.
编辑
如评论中所述,期望是一个“魔术”边界,用于隔离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
推荐阅读
- oracle - Oracle 在使用 IN 子句的查询中选择更新行为
- mongodb - MongoDb 在并非所有文档中的字段上创建唯一索引
- linux - bash 上的命令变量内的变量
- javascript - 将 window.open 与不与 Cordova 或 Electron 一起使用的 blob 文件一起使用
- python - 在自己的数据集上训练时,deeplab 从检查点恢复失败
- ruby-on-rails - FactoryBot 一条记录与许多属性相关联
- blockchain - 区块奖励与区块链中的交易费用
- java - 如何使用 servlet 4.0 配置 taglib
- google-analytics - 为什么计时器会生成一个新会话?
- java - 比较两个 XMl 文件忽略元素和属性顺序 Java eclipse