我只知道从Delphi XE7有并行。这很酷。所以我尝试转换一小段代码,例如:
procedure TestParallel;
var
i, j, u, v: integer;
map: array of array of integer;
begin
SetLength(map, 101, 101);
u := 100; v := 100;
for i := 0 to u do
begin
for j := 0 to v do
begin
if (map[i][j] <> 0) then
begin
map[i][j] := 1;
end;
end;
end;
end;
:
procedure TestParallel;
var
i, u, v: integer;
map: array of array of integer;
begin
SetLength(map, 101, 101);
u := 100; v := 100;
TParallel.&For(0, u, procedure(i: integer)
var
j: integer;
begin
for j := 0 to v do
begin
if (map[i][j] <> 0) then
begin
map[i][j] := 1;
end;
end;
end);
end;
更新
是的,上面的代码可以编译,而下面的代码不能(如果map数组作为var参数传递)
type
data = array of array of integer;
procedure TestParallel(var map: data);
var
i, u, v: integer;
begin
SetLength(map, 101, 101);
u := 100; v := 100;
TParallel.&For(0, u, procedure(i: integer)
var
j: integer;
begin
for j := 0 to v do
begin
if (map[i][j] <> 0) then
begin
map[i][j] := 1;
end;
end;
end);
end;
不幸的是,编译器说:
[dcc64 Error] Project2.dpr(70): E2555 Cannot capture symbol 'map'
那么,如何使这个工作尽可能简单呢?
此代码与问题中的代码相同,在Delphi XE7 update 1上同时在dcc32和dcc64上编译。
program Project1;
uses
System.Threading;
procedure TestParallel;
var
i, u, v: integer;
map: array of array of integer;
begin
SetLength(map, 101, 101);
u := 100; v := 100;
TParallel.&For(0, u, procedure(i: integer)
var
j: integer;
begin
for j := 0 to v do
begin
if (map[i][j] <> 0) then
begin
map[i][j] := 1;
end;
end;
end);
end;
begin
end.
编译器观察到,TestParallel
中的局部变量i
是未使用的,应该删除。这没什么区别。
我无法解释为什么您无法编译此代码。要么你用的编译器和我不一样,要么你的代码和我不一样。
事实上,从你的问题更新,事实证明,你没有张贴不编译的代码。
这里最大的教训是,永远不要发布虚假代码。如果可能的话,一定要发布真实的代码,完整的代码,尽可能少。
对于您刚刚发布的实际代码,它看起来像这样:
procedure TestParallel(var map: data);
var
i, u, v: integer;
begin
SetLength(map, 101, 101);
u := 100; v := 100;
TParallel.&For(0, u, procedure(i: integer)
var
j: integer;
begin
for j := 0 to v do
begin
if (map[i][j] <> 0) then
begin
map[i][j] := 1;
end;
end;
end);
end;
编译失败,因为无法捕获var参数。编译器必须能够在编译声明变量的函数时看到捕获是必要的。对于var
参数,编译器不知道变量在哪里声明。参见匿名方法变量绑定:
匿名方法的一个关键特性是它们可以引用在定义它们的地方对它们可见的变量。
您需要使用以下内容:
procedure TestParallel(var map: TArray<TArray<Integer>>);
var
LocalMap: TArray<TArray<Integer>>;
u, v: integer;
begin
SetLength(LocalMap, 101, 101);
TParallel.&For(0, high(LocalMap), procedure(i: integer)
var
j: integer;
begin
for j := 0 to high(LocalMap[i]) do
begin
if (LocalMap[i][j] <> 0) then
begin
LocalMap[i][j] := 1;
end;
end;
end);
map := LocalMap;
end;
声明一个可以捕获的局部变量。然后我们可以在循环完成后赋值给var
参数。好吧,我们可以在循环开始前相等地赋值,但我觉得这在语义上很奇怪。