for each 居然不能用来赋值..

2018 年 6 月 20 日
 richieboy

一直以为是等价的..好坑啊,还是老实用 for 循环了

5407 次点击
所在节点    Java
20 条回复
Sinar
2018 年 6 月 20 日
赋值用 map 吧
bumz
2018 年 6 月 20 日
C++ 就行

for (auto & a : b) {
a = 0;
}
0x11901
2018 年 6 月 20 日
for each 只是遍历,赋值用 map(std::transform)
LangInteger
2018 年 6 月 20 日
归根结底,还是因为 java 只有值传递吧~
bumz
2018 年 6 月 20 日
@Sinar map 不是赋值,是创建新的吧
xomix
2018 年 6 月 20 日
遍历中赋值会导致遍历集合变更,如果要支持便利赋值就要支持便利的时候便利的不再是键值对组合,利用对象复制等功能可以牺牲资源换可读性。

.net 写法如下,java 我不是很熟练不在这里班门弄斧了。

Dictionary<string, string> lst = new Dictionary<string, string>() { { "1", "1" }, { "2", "2" } };
foreach (string key in lst.Keys.ToList())
{
lst[key] = lst[key] + "hello";
}


这里对 keys 的集合进行了一个 ToList(),实现了一个对象复制,这时候修改原对象就不会造成便利的集合更改了。

java 可能没有 Linq 支持 ToList()这个方法我就不知道该怎么写了。
Magentaize
2018 年 6 月 20 日
foreach 是访问者模式
Narcissu5
2018 年 6 月 20 日
foreach 是函数式的方法,函数式的基本特征之一就是不可变。

也就是如果需要修改的话,返回一个新列表而不是修改之前的
congeec
2018 年 6 月 20 日
@Narcissu5 把你这句话里的 foreach 换成 map
lurenw
2018 年 6 月 20 日
java 的 closure 是 capture by value 的。如果要修改,考虑用一个长度为 1 的数组来传外部变量吧。
ShineSmile
2018 年 6 月 20 日
没记错 foreach 是与 IEnumable 接口相关?
0x11901
2018 年 6 月 20 日
@bumz 你这么写不好,赋值用 auto &&a
geelaw
2018 年 6 月 20 日
@bumz #2 那是因为 C++ 的遍历实质上是遍历元素的指针(或者访问器),其他语言是遍历元素的 copy

@0x11901 #12 为什么?
geelaw
2018 年 6 月 20 日
@0x11901 #12
@geelaw #13

I see. 在访问器的情况下 auto & 会失败
0x11901
2018 年 6 月 20 日
@geelaw 对,一般在生产中要改变元素用 auto &&,不变用 const auto &。
ShineSmile
2018 年 6 月 20 日
感觉是不是还要详细学一下 yield ?
looplj
2018 年 6 月 20 日
Java 中的 lambda 捕获的变量只能是 final 或者是实质不可变的。
以后应该会改成可以捕获可变的吧。
szq8014
2018 年 6 月 21 日
java 里面 foreach 是用 iterator 来实现的
bumz
2018 年 6 月 21 日
@0x11901
@geelaw

可否简单举例 auto & 失效的情况?
bumz
2018 年 6 月 21 日
@bumz I see, 例如 std::vector<bool>

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/464367

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX