是否有“匿名递归”和“rdquo;在.NET工作?它在Mono
几天前我在“C#匿名递归”中浏览了这个网站。本文的主旨是以下代码在C#中不起作用:
Func<int, int> fib = n => n > 1 ? fib(n - 1) + fib(n - 2) : n;
然后,文章详细介绍了如何使用currying和Y-combinator回到C#中的“Anonymous Recursion”。这很有趣,但我担心日常编码有点复杂。此时至少......
我喜欢看自己的东西,所以我打开了Mono CSharp REPL并输入了该行。没有错误。所以,我进入了fib(8);
。令我非常惊讶的是,它奏效了! REPL回复了21
!
我想也许这可能是REPL的一些魔力,所以我解雇了'vi',输入以下程序,然后编译它。
using System;
public class Program
{
public static void Main(string[] args)
{
int x = int.Parse(args[0]);
Func<int, int> fib = n => n > 1 ? fib(n - 1) + fib(n - 2) : n;
Console.WriteLine(fib(x));
}
}
它也完美地建造和运行!
我在Mac上运行Mono 2.10。我现在无法访问Windows计算机,所以我无法在Windows上的.NET上进行测试。
这是在.NET上修复过的还是Mono的静音功能?这篇文章已经有几年了。
如果它只是单声道,我不能等待下一次面试,他们要求我用我选择的语言(Mono C#)编写Fibinocci函数,我必须提供.NET无法使用的警告。好吧,实际上我可以等,因为我热爱自己的工作。还是有意思......
更新:
Mono并没有真正进行“匿名”递归,因为它使用fib
作为命名委托。我的错。事实上,Mono C#编译器在赋值之前假定null
的值为null
,这是一个错误,如下所述。我说“编译器”是因为即使.NET C#编译器无法编译代码,.NET CLR也能正常运行生成的程序集。
对于所有采访纳粹在那里:
Func<int, int> fib = n => n > 1 ? fib(n - 1) + fib(n - 2) : n;
可以用迭代版本替换:
Func<int, int> fib = n =>
{
int old = 1;
int current = 1;
int next;
for (int i = 2; i < n; i++)
{
next = current + old;
old = current;
current = next;
}
return current;
};
您可能希望这样做,因为递归版本在C#等语言中效率低下。有些人可能会建议使用memoization但是,因为它仍然比迭代方法慢,所以它们可能只是游荡者。 :-)
在这一点上,这变得更像是一个功能编程的广告而不是其他任何东西(因为递归版本更好)。它与我原来的问题没有任何关系,但有些答案认为这很重要。
没有找到相关结果
已邀请:
5 个回复
扑北爱
佩疵瓦
栖很钾是狠
...问题是当您尝试在上述方法中使用fib时未定义fib,因此静态分析器报告编译器错误。
靛取糕奖穿
。 在Mono C#REPL中查看以下序列:
这是因为:
换一种说法,
显然,
只是指向
(代表)的当前定义而不是其本身。因此,Mono实际上只是在初始分配期间预先将
的值分配给
,以便赋值有效。 我更喜欢不必申报
的便利,所以我喜欢这种行为。尽管如此,它并不是原始文章所说的。
掏得透垦滩
设置为
时才有效。 否则,它将给出错误,因为在分配之前使用
。 Mono的编译器“足够智能”以避免此错误(换句话说,它违反了官方规范)