【问题标题】:Groovy - Closures and bind, why this code doesn't work?Groovy - 闭包和绑定,为什么这段代码不起作用?
【发布时间】:2010-09-10 15:42:37
【问题描述】:

我认为这是一个新手问题,但为什么它在最后一个断言上失败了? 我在想闭包绑定了它上面的值,所以从闭包中改变它会改变闭包之外的值。

def value = 5

def foo(n){

  return {

    ++n

  }
}

def test = foo(value)

assert test() == 6
assert test() == 7

assert value == 7

感谢您的帮助。

【问题讨论】:

    标签: groovy closures


    【解决方案1】:

    这似乎是一种奇怪的行为,但我认为这是正确的。所有对象事件整数都通过引用传递。调用 foo(value) 将值传递给函数。变量“n”是对与“值”引用相同的对象的引用。本质上,您有两个指向同一个对象的指针。当你增加“n”时,你只是在增加那个变量。

    由于 Integer 类是不可变的 ++n 实际上是在做类似的事情:

    n = n + 1
    

    这是将递增的值分配给变量 n。顶部声明的变量 'value' 仍然指向原始对象 5。

    【讨论】:

      【解决方案2】:

      请记住,整数(value 的运行时类型)是不可变的。因此,虽然nvalue 最初指的是同一个对象,但当您执行++n 时,它会创建一个新的Integervalue 引用没有更新为引用这个新对象,所以当执行完成时它仍然引用初始对象 (5)。

      【讨论】:

        【解决方案3】:

        您正在为名称 n 分配一个新值,该值与名称 value 不同。您可以通过将value 设为可变对象来获得所需的行为。然后您可以更改它而不是创建和分配新对象。

        这是一个将值包装在列表中的简单示例:

        def value = [5]
        
        def foo(n){
        
            return {
        
                n[0]++
                n
            }
        }
        
        def test = foo(value)
        
        assert test() == [6]
        assert test() == [7]
        
        assert value == [7]
        

        【讨论】:

          猜你喜欢
          • 2017-08-22
          • 2017-05-24
          • 1970-01-01
          • 2010-09-18
          相关资源
          最近更新 更多