将类型字段或数组元素用作循环计数器无效
Invalid use of a type field or array element as a loop counter
在下面的代码中,我尝试使用字段变量(class 或记录)或数组元素直接作为循环计数器,但这是非法的("error: invalid index expression")。这仅仅是因为循环计数器必须是标量变量吗?
class Cls {
var n: int;
}
proc main()
{
var x = new Cls( 100 );
var k: [1..10] int;
for x.n in 1..3 do // error: invalid index expression
writeln( x.n );
for k[1] in 1..3 do // error: invalid index expression
writeln( k[1] );
}
另一方面,如果我创建对 x.n
的引用,它编译成功但外部作用域中的 x
未被修改。这是因为在 for 循环中创建了一个名为 n
的新循环变量吗? (恐怕和我的另一个几乎一样...)
proc main()
{
var x = new Cls( 100 );
ref n = x.n;
for n in 1..3 do
writeln( n );
writeln( "x = ", x ); // x = {n = 100}
}
如果一个循环变量是独立创建的,我想如果我写 for x.n in 1..3
可能会发生类似 "var x.n = ..." 的事情(内部),这似乎真的无效(因为这意味着我正在尝试声明一个名为 x.n
).
的循环变量
你是对的,这与你的. As described there, Chapel's for-loops create new index variables to store the values yielded by the iterator expression(s), so a loop like for i in ...
results in a new variable i
being declared rather than using an existing variable or expression. If you think the error message should be improved to make this clearer, please consider suggesting a new wording in a GitHub issue有关。
请注意,除了单个变量名称外,循环还可以使用索引变量的元组来捕获压缩迭代或产生元组值的 iterand 的结果。例如,以下压缩迭代的值可以捕获为标量值 i
和 j
:
for (i,j) in zip(1..3, 2..6 by 2) do // store values in 'i' and 'j' respectively
writeln((i,j));
或作为元组类型的单个变量:
for ij in zip(1..3, 2..6 by 2) do // store values in 2-tuple 'ij'
writeln(ij);
类似地,当迭代产生元组值的东西时,例如多维索引集,结果可以捕获为标量值或元组:
const D = {1..3, 0..2}; // declare a 2D rectangular domain
for (i,j) in D do // store indices in new scalars 'i' and 'j'
writeln((i,j));
for ij in D do // store indices in new 2-tuple 'ij'
writeln(ij);
return 更大或嵌套元组的更复杂的迭代器,可以类似地在索引变量的声明中去元组或不去元组。
在下面的代码中,我尝试使用字段变量(class 或记录)或数组元素直接作为循环计数器,但这是非法的("error: invalid index expression")。这仅仅是因为循环计数器必须是标量变量吗?
class Cls {
var n: int;
}
proc main()
{
var x = new Cls( 100 );
var k: [1..10] int;
for x.n in 1..3 do // error: invalid index expression
writeln( x.n );
for k[1] in 1..3 do // error: invalid index expression
writeln( k[1] );
}
另一方面,如果我创建对 x.n
的引用,它编译成功但外部作用域中的 x
未被修改。这是因为在 for 循环中创建了一个名为 n
的新循环变量吗? (恐怕和我的另一个几乎一样
proc main()
{
var x = new Cls( 100 );
ref n = x.n;
for n in 1..3 do
writeln( n );
writeln( "x = ", x ); // x = {n = 100}
}
如果一个循环变量是独立创建的,我想如果我写 for x.n in 1..3
可能会发生类似 "var x.n = ..." 的事情(内部),这似乎真的无效(因为这意味着我正在尝试声明一个名为 x.n
).
你是对的,这与你的for i in ...
results in a new variable i
being declared rather than using an existing variable or expression. If you think the error message should be improved to make this clearer, please consider suggesting a new wording in a GitHub issue有关。
请注意,除了单个变量名称外,循环还可以使用索引变量的元组来捕获压缩迭代或产生元组值的 iterand 的结果。例如,以下压缩迭代的值可以捕获为标量值 i
和 j
:
for (i,j) in zip(1..3, 2..6 by 2) do // store values in 'i' and 'j' respectively
writeln((i,j));
或作为元组类型的单个变量:
for ij in zip(1..3, 2..6 by 2) do // store values in 2-tuple 'ij'
writeln(ij);
类似地,当迭代产生元组值的东西时,例如多维索引集,结果可以捕获为标量值或元组:
const D = {1..3, 0..2}; // declare a 2D rectangular domain
for (i,j) in D do // store indices in new scalars 'i' and 'j'
writeln((i,j));
for ij in D do // store indices in new 2-tuple 'ij'
writeln(ij);
return 更大或嵌套元组的更复杂的迭代器,可以类似地在索引变量的声明中去元组或不去元组。