kos*_*hei 4 foreach delegates d pass-by-reference
产生问题的示例代码:
import std.stdio, core.thread;
void main() {
ThreadGroup tg = new ThreadGroup();
foreach (int i; 1 .. 5)
tg.create( () => writeln(i) );
tg.joinAll();
}
Run Code Online (Sandbox Code Playgroud)
样本输出:
3
5
5
5
5
Run Code Online (Sandbox Code Playgroud)
(预期输出为整数1到5)
我不明白为什么会发生这种情况 - i不是引用类型,也没有引用它在委托中使用,所以为什么每个线程使用的值i作为线程所在的任何值预定的,而不是它给出的大概传值值?
我做了一些这样的蹩脚尝试,但没有成功:
foreach (int i; 1 .. 5) {
scope j = i;
tg.create( () => writeln(j) );
}
Run Code Online (Sandbox Code Playgroud)
我很好奇为什么这不起作用.是不是j每次都宣布新鲜的?为什么每个线程引用相同的j(在线程调度时它的值通常为5)?
那么为什么每个线程使用i的值作为调度线程时它碰巧具有的值,而不是它给出的大概传值值?
就循环体而言,它是pass-by-value,但是这不适用于在其中创建的线程.线程仍将i通过其地址引用.
要解决此问题,您需要在循环内创建一个闭包:
import std.stdio, core.thread;
void main() {
ThreadGroup tg = new ThreadGroup();
foreach (int i; 1 .. 5)
(i =>
tg.create( () => writeln(i) )
)(i);
tg.joinAll();
}
Run Code Online (Sandbox Code Playgroud)
lambda参数将存储在闭包中,为每个线程提供自己的副本.
| 归档时间: |
|
| 查看次数: |
61 次 |
| 最近记录: |