我幾天前在「匿名遞歸C#」中衝浪到this網站。文章的主旨是,下面的代碼將不會在C#中的工作:「匿名遞歸」在.NET中工作嗎?它在單聲道
Func<int, int> fib = n => n > 1 ? fib(n - 1) + fib(n - 2) : n;
文章然後進入有關如何使用currying一些細節和Y-combinator在C#回到「匿名遞歸」。這很有意思,但我擔心我的日常編碼有點複雜。在這一點上至少...
我喜歡看到自己的東西,所以我打開單聲道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不起作用的警告。呃,其實我可以等我喜歡我的工作。不過,有趣的......
更新:
單是不是真的在做「匿名」遞歸,因爲它是用fib
爲命名的委託。我的錯。在賦值之前,Mono C#編譯器假設null
值爲fib
,這一事實如下所述。我說「編譯器」,因爲即使.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,但是,由於這種方法仍然比迭代方法慢,所以它們可能只是流浪者。 :-)
但是,在這一點上,這變成了功能性編程的廣告,而不是其他任何東西(因爲遞歸版本非常好)。這與我原來的問題確實沒有任何關係,但有些答案認爲這很重要。
如果有工作面試者問我我會走出去。 – JonH 2011-03-30 14:56:38
最後我檢查了你還必須在另外一行聲明'Func',我很樂意錯誤! – BrokenGlass 2011-03-30 14:57:19
試過了,C#3.5失敗了。 – 2011-03-30 14:59:10