2

例子

此测试失败,因为each不修改列表的元素。

void test_each_DoesNotModifyListElements() {
    List<String> list = ["a", "b", "c"]
    list.each { it =  it + "z" }
    assert ["az", "bz", "cz"] == list
}

这个测试通过了,因为collect返回了一个包含修改过的元素的新列表。

void test_collect_ReturnsNewListWithModifiedElements() {
    List<String> list = ["a", "b", "c"]
    list = list.collect{ it + "z" }
    assert ["az", "bz", "cz"] == list
}

假设

在这一点上,我假设它each不会修改列表的元素,因为我已经编写了下面的测试并且我假设这就是测试告诉我的。如果我错了,请纠正我。

void test_each_DoesNotModifyListElements1() {
    List<String> list = ["a", "b", "c"]
    list.each { it + "z" }
    assert ["az", "bz", "cz"] == list
}

void test_each_DoesNotModifyListElements2() {
    List<String> list = ["a", "b", "c"]
    list.each { it =  it + "z" }
    assert ["az", "bz", "cz"] == list
}

void test_each_DoesNotModifyListElements3() {
    List<String> list = ["a", "b", "c"]
    list = list.each { it =  it + "z" }
    assert ["az", "bz", "cz"] == list
}

问题

所以问题是:作为一个 Groovy 初学者,我应该怎么知道,在编写测试和谷歌搜索之前,这each不会改变列表的元素?

通过阅读文档?

Groovy 每个文档:迭代聚合类型或数据结构,将每个项目传递给给定的闭包。自定义类型可以通过简单地提供“iterator()”方法来使用此方法。从结果迭代器返回的项目将被传递给闭包。

通常,我最终会花费大量时间尝试并在谷歌上搜索答案。不应该有更有效的方法吗?在那儿?

4

2 回答 2

5

嗯,这离 Java/Groovy 编程基础不远了。有对象,也有变量。变量可以保存到对象的“链接”,称为引用。所以基本上,使用变量你可以访问存储在计算机内存深处的真实对象。

每当您更改变量(即为其分配某些内容)时,您永远不会修改真实对象。相反,变量开始指向一些不同的对象。

现在,再次查看文档:

遍历聚合类型或数据结构,将每个项目传递给给定的闭包。

这就是它所做的一切。它为您提供了一个指向每个项目的变量。如果你覆盖了你给定的局部变量,变量开始指向其他对象,就是这样。该列表仍然具有对旧对象的引用。

这些信息是用 Java 和类似语言编程所需的最基本知识。通常在手册/文档的第一页进行解释。而且因为它是基本的,所以没有人会为你有某种参数的每个函数一遍又一遍地解释它。

于 2013-05-08T10:36:26.383 回答
1

@Max 在上面提供了一个很好的答案。我的 2 美分就可以了。变量或引用实际上是在java中按值传递的。了解这一点也很重要。请注意,对象本身不会被复制,只会复制对它的引用。

现在让我们回到列表。它引用了其中的所有对象。当您each在列表上调用时,会创建一个指向同一对象的引用并将其传递给该方法。因此,即使您使这个新创建的引用变量指向不同的对象,列表中的引用仍然保持不变并指向同一个旧对象。each

于 2013-08-26T14:27:32.897 回答