在过去一年左右的时间里,我一直在尝试Chapel.我过去曾简单地使用过C和C++,但我最近的经验是使用Python,Ruby和Erlang等动态语言.
在接触到Erlang及其功能条款后,我很高兴能够找到Chapel中的子句.但是,我在使用它时遇到了障碍.在Y分钟内学习Chapel包含以下代码,演示如何使用where子句:
proc whereProc(param N : int): void
where (N > 0) {
writeln("N is greater than 0");
}
proc whereProc(param N : int): void
where (N < 0) {
writeln("N is less than 0");
}
whereProc(10);
whereProc(-1);
Run Code Online (Sandbox Code Playgroud)
这会为两个标量值10和-1中的每一个生成预期输出.但是,我试图编写迭代范围或数组的类似程序.我甚至尝试过递归.在所有情况下,我得到基本相同的错误:
whereproc2.chpl:12: error: unresolved call 'whereProc(int(64))'
whereproc2.chpl:1: note: candidates are: whereProc(param N: int)
whereproc2.chpl:6: note: whereProc(param N: int)
Run Code Online (Sandbox Code Playgroud)
产生此特定错误的代码是:
proc whereProc(param N : int): void
where (N > 0) {
writeln("N is greater than 0");
}
proc whereProc(param N : int): void
where (N <= 0) {
writeln("N is less than or equal to 0");
}
for n in 1..10 do
whereProc(n);
Run Code Online (Sandbox Code Playgroud)
是否有一些我缺少会导致这种情况发生的事情,或者预计这不起作用?我注意到在Y分钟的学习礼拜堂上,它说所有信息都需要在编译时知道.编译时是否知道有限范围或初始化数组的内容?在我看来,如果只使用标量值,那么where子句的用处是有限的.
我缺少什么东西会导致这个工作......?
是的,问题是在你的for循环中:
for n in 1..10 do
whereProc(n);
Run Code Online (Sandbox Code Playgroud)
当迭代范围时,循环索引变量n是一个执行时常量,这会阻止编译器对其进行推理。为了获得您想要的行为,您需要请求编译器将其设为param(编译时常量)。这可以使用以下语法来完成:
for param n in 1..10 do
whereProc(n);
Run Code Online (Sandbox Code Playgroud)
n这具有创建一个值的效果param,该值使编译器能够推断其值。 在线尝试这个版本的代码(范围稍微更有趣)。
使用像这样的参数索引表达式可以被视为完全展开循环:
{
param n = 1;
whereProc(n);
}
{
param n = 2;
whereProc(n);
}
...
{
param n = 10;
whereProc(n);
}
Run Code Online (Sandbox Code Playgroud)
因此,当类型可能从一次迭代到下一次迭代(如异构元组)时,这可能是一种有用的迭代方式。