I just know From Delphi XE7 there is Parallel.For which is cool. so I try to convert a small piece of code, such as:
我从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;
to :
:
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;
UPDATE
更新
Yes, above code compiles, and the following is not (if the map array is passed as var parameter)
是的,上面的代码是编译的,下面的不是(如果将映射数组作为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;
But unfortunately, the compiler says:
但不幸的是,编译器说:
[dcc64 Error] Project2.dpr(70): E2555 Cannot capture symbol 'map'
So, how to make this work as simple as possible?
那么,如何使这项工作尽可能简单呢?
1 个解决方案
#1
4
This code, identical to that in the question, compiles in both dcc32 and dcc64, on Delphi XE7 update 1.
该代码与问题中的相同,在Delphi XE7更新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.
The local variable i
in TestParallel
is unused, as the compiler observes, and should be removed. Not that it makes any difference.
在TestParallel中,本地变量i是未使用的,正如编译器所观察到的,并且应该被删除。并不是说它有什么不同。
I cannot explain why you are unable to compile this code. Either you are using a different compiler from me, or have different code from me.
我无法解释你为什么不能编译这段代码。要么你用的是不同的编译器,要么有不同的代码。
Update
更新
And indeed, from your question update, it turns out that you have not posted the code that does not compile.
实际上,从您的问题更新中,我们发现您没有发布不编译的代码。
The big lesson here, is never to post fake code. Always post real code, complete code if at all possible, as minimal as you can.
这里的重要教训是,永远不要发布虚假代码。总是发布真正的代码,如果可能的话完整的代码,尽可能的少。
As for your real code, that you have just posted, that looks like this:
至于你的真实代码,你刚刚发布的,看起来是这样的:
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;
That fails to compile because var parameters cannot be captured. The compiler has to be able to see that a capture is necessary when compiling the function that declares the variable. For a var
parameter, the compiler has no knowledge of where the variable is declared. See Anonymous Methods Variable Binding:
无法编译,因为无法捕获var参数。编译器在编译声明变量的函数时,必须能够看到捕获是必需的。对于一个var参数,编译器不知道变量在哪里声明。见匿名方法变量绑定:
A key feature of anonymous methods is that they may reference variables that are visible to them where they were defined.
匿名方法的一个关键特性是,它们可以引用被定义的变量。
You need to use something along these lines:
你需要沿着这些线使用一些东西:
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;
We declare a local which we can then capture. Then we can assign to the var
parameter after the loop has completed. Well, we could equally assign before the loop starts but that feels semantically odd to me.
我们声明一个我们可以捕捉到的地方。然后我们可以在循环完成后分配到var参数。我们可以在循环开始之前分配,但这对我来说有点奇怪。
#1
4
This code, identical to that in the question, compiles in both dcc32 and dcc64, on Delphi XE7 update 1.
该代码与问题中的相同,在Delphi XE7更新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.
The local variable i
in TestParallel
is unused, as the compiler observes, and should be removed. Not that it makes any difference.
在TestParallel中,本地变量i是未使用的,正如编译器所观察到的,并且应该被删除。并不是说它有什么不同。
I cannot explain why you are unable to compile this code. Either you are using a different compiler from me, or have different code from me.
我无法解释你为什么不能编译这段代码。要么你用的是不同的编译器,要么有不同的代码。
Update
更新
And indeed, from your question update, it turns out that you have not posted the code that does not compile.
实际上,从您的问题更新中,我们发现您没有发布不编译的代码。
The big lesson here, is never to post fake code. Always post real code, complete code if at all possible, as minimal as you can.
这里的重要教训是,永远不要发布虚假代码。总是发布真正的代码,如果可能的话完整的代码,尽可能的少。
As for your real code, that you have just posted, that looks like this:
至于你的真实代码,你刚刚发布的,看起来是这样的:
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;
That fails to compile because var parameters cannot be captured. The compiler has to be able to see that a capture is necessary when compiling the function that declares the variable. For a var
parameter, the compiler has no knowledge of where the variable is declared. See Anonymous Methods Variable Binding:
无法编译,因为无法捕获var参数。编译器在编译声明变量的函数时,必须能够看到捕获是必需的。对于一个var参数,编译器不知道变量在哪里声明。见匿名方法变量绑定:
A key feature of anonymous methods is that they may reference variables that are visible to them where they were defined.
匿名方法的一个关键特性是,它们可以引用被定义的变量。
You need to use something along these lines:
你需要沿着这些线使用一些东西:
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;
We declare a local which we can then capture. Then we can assign to the var
parameter after the loop has completed. Well, we could equally assign before the loop starts but that feels semantically odd to me.
我们声明一个我们可以捕捉到的地方。然后我们可以在循环完成后分配到var参数。我们可以在循环开始之前分配,但这对我来说有点奇怪。