Groovy - 闭包和绑定,为什么这段代码不起作用?

发布于 2024-09-19 04:54:39 字数 246 浏览 9 评论 0原文

我认为这是一个新手问题,但为什么最后一个断言失败了? 我认为闭包绑定了它上面的值,因此从闭包中更改它将会更改闭包外部的值。

def value = 5

def foo(n){

  return {

    ++n

  }
}

def test = foo(value)

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

assert value == 7

感谢您的帮助。

I think this is a newbie question but why it fails on the last assertion?
I was thinking that the closure binds the value on it, so changing it from the closure will change the value outside the closure.

def value = 5

def foo(n){

  return {

    ++n

  }
}

def test = foo(value)

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

assert value == 7

Thanks for help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

小姐丶请自重 2024-09-26 04:54:39

这确实看起来很奇怪,但我认为这是正确的。所有对象事件整数均通过引用传递。调用 foo(value) 将值传递给函数。变量“n”是对与“值”引用相同的对象的引用。本质上你有两个指向同一个对象的指针。当您增加“n”时,您仅增加该变量。

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

n = n + 1

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

That does seem to be strange behaviour but I think it is correct. All objects event integegers are passed by reference. The call foo(value) passes value into the function. The variable 'n' is a reference to the same object as 'value' references. Essentially you have two pointers to the same object. When you increment 'n', you are incrementing that variable only.

Since the Integer class is immutable ++n is actually doing something like:

n = n + 1

This is assigning the incremented value to the variable n. The variable 'value' declared at the top is still pointing to the original object 5.

与君绝 2024-09-26 04:54:39

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

Remember that Integer (the runtime type of value) is immutable. So although n and value initially refer to the same object, when you execute ++n it creates a new Integer. The value reference is not updated to refer to this new object, so when execution completes it is still referring to the initial object (5).

美煞众生 2024-09-26 04:54:39

您正在为名称 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]

You are assigning a new value to the name n, which is different than the name value. You can get the behaviour you want by making value a mutable object. Then you can change it instead of creating and assigning a new object.

Here's a simple example that wraps the value in a list:

def value = [5]

def foo(n){

    return {

        n[0]++
        n
    }
}

def test = foo(value)

assert test() == [6]
assert test() == [7]

assert value == [7]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文