我一直在尝试在Oxygene中使用Lambda表达式。用于计算斐波那契数的非常简单的递归lambda表达式:
var fib : Func<int32, int32>;
fib := n -> iif(n > 1, fib(n - 1) + fib(n - 2), n);
fib(3);当我运行这段代码时,我得到了一个nullreferenceexception。知道我做错了什么吗?
发布于 2008-11-06 22:23:46
你没有做错任何事。如果有的话,编译器应该警告你在lambda的主体中使用fib,一个未赋值的变量。
然而,编译器应该捕获fib作为一个位置,这样当赋值完成后,委托被调用时,fib被正确赋值,递归应该按预期工作。
失败的最明显的可能原因是,Prism没有捕获位置,而是值,这将是非常不直观的,并且与非纯语言中的所有其他闭包实现不一致。
例如,在JavaScript中尝试以下代码(与克雷格在这篇文章的评论中的断言相反,JavaScript也捕获位置,而不是值):
<html>
<head>
<script language='javascript'>
function main()
{
var x = 1;
var f = function() { return x; };
alert(f());
x = 2;
alert(f());
}
</script>
</head>
<body>
<input type=button onclick="javascript:main()"></input>
</body>
</html>单击按钮后的警告框分别显示1和2,而遵循Prism/Oxygene语义,它们两次都会显示1。
发布于 2009-09-29 08:40:54
史蒂夫:
这个问题显然已经在Delphi Prism 2010中得到了解决。以下代码示例在官方版本中有效。
var fib : Func<int32, int32>;
fib := n -> iif(n > 1, fib(n - 1) + fib(n - 2), n);
var i := fib(9); //1,1,2,3,5,8,13,21,34
MessageBox.Show(i.ToString);MessageBox显示值34。
为了回答Jeroen的问题,此代码在原始的官方发布版本3.0.21.661中运行。
发布于 2008-11-07 13:20:10
作为临时解决方法,您可以使用:
var f := new class(f: Tfib := nil);
f.f := method(n : Int32): Int32
begin
if n > 1 then
Result := f.f(n-1) + f.f(n-2)
else
Result := n;
end;
f.f(3);https://stackoverflow.com/questions/270350
复制相似问题