Delphi:用于“for In”的变量无法分配!

时间:2010-02-11 16:57:04

标签: delphi delphi-2010

为什么编译器不允许for ... in循环中的赋值?

procedure TForm1.Button1Click(Sender: TObject);
Var
  ars : Array [0..10] of Integer;
  s : Integer;
  ct : Integer;
begin
  ct := 0;
  for s in ars do
  Begin
    s := ct; // Does not compile!
    Inc(ct);
  End;
End;

5 个答案:

答案 0 :(得分:8)

这不受支持,就像在“正常”for循环中无法修改简单的循环迭代器变量一样。即使这在 for-in 中得到支持,在这种情况下也没有多大意义。

整数是值类型,因此在循环的每次迭代中,所有可以实现的是 s 将初始化为数组元素的值,然后 s Ct 覆盖。

但是数组内容被修改,代码的净效果将是“无变化”。

要获得您对 for-in 的期望,您必须能够使用合适的引用类型进行迭代(在本例中为 PInteger - 指向整数的指针)产生引用到数组元素,而不是这些元素的值的副本。然后可以使用解除引用的指针分配每个元素的新值:

var
  ars : array [0..10] of Integer;
  s : PInteger;
  ct : Integer;
begin
  ct := 0;
  for s in ars do  // << this WON'T yield pointers to the array elements ..
  begin
    s^ := Ct;      // .. but if it did you could then write this
    Inc(ct);
  end;
end;

但是不要激动 - 这也不会起作用,它只是表明问题的本质源于参考与价值的差异。

答案 1 :(得分:5)

我对Delphi一无所知。但是,大多数语言不允许您在foreach中分配迭代变量。你为什么要这样做?

答案 2 :(得分:2)

只需使用while循环。

procedure TForm1.Button1Click(Sender: TObject);
Var
  ars : Array [0..10] of Integer;
  i : Integer;
  ct : Integer;
begin
  ct := 0;
  i := 0;
  while i < Length(ars) do
  Begin
    ars[i] := Ct; //Does Compile!
    Inc(ct);
    inc(i);
  End;
End;

答案 3 :(得分:1)

为了更好地理解这一点,我会说,“理解s是由for s in .... construct”控制的,也就是说,当s控制for循环时,一个编写良好的编译器几乎任何语言都会阻止你这样做。任何编写得不够好的编译器都应该通过编译器警告来备份,或者是一个lint工具,它表明你正在做一些最好的,非常糟糕的风格,最坏的情况可能会导致一些难以预测的“未定义”行为。如果将s设置为高于Length(ars)的值,​​会发生什么?循环应该中止,还是应该继续?

答案 4 :(得分:1)

变量S只是数组中值的副本,因此更改它没有任何意义。构造

for s in ars do

基本等同于

for i := low(ars) to high(ars) do
  s := ars[i]

所以没有必要分配给S.以这种方式循环

procedure TForm1.Button1Click(Sender: TObject);
Var
  ars : Array [0..10] of Integer;
  i : Integer;
  ct : Integer;
begin
  ct := 0;
  for i := low(ars) to high(ars) do
  Begin
    ars[i] := ct;
    Inc(ct);
  End;
End;