2015-09-04 86 views
1

我自己從scala編譯器源代碼構建一個scala編譯器。在編譯器的源代碼中,有許多尾遞歸函數/方法。從其源代碼構建scala編譯器還需要編譯編譯器本身的源代碼。如果我添加的選項-g:notailcalls編譯源代碼時關閉尾遞歸優化,運行內置的編譯器時,會出現一個statck溢出錯誤。scala中沒有尾遞歸優化時堆棧溢出?

總而言之,是否有可能在一個大型且複雜的scala程序中有很多遞歸調用時,在編譯時可能會導致運行時出現堆棧溢出錯誤,而不進行尾遞歸優化?

+0

當然,你可以檢查[issues](https://issues.scala-lang.org/browse/SI-9048?jql=text%20~%20%22stackoverflow%22) – 4e6

+0

是的,當然。關閉尾遞歸優化意味着否則尾遞歸函數的遞歸調用會消耗堆棧幀,因此佔用更多堆棧並使堆棧溢出的可能性更大。 –

+1

它不需要一個「大而複雜」的程序。只需嘗試一下:'def f(i:Int):Int = if(i == 0)i else f(i - 1); F(1000000)' –

回答

2

當然。但請注意Scala是能夠找出如果函數是尾遞歸本身,你不需要到@tailrec註釋傳遞給函數。

然而,Scala是無法轉化合適的功能到其尾遞歸形式。你必須手動做到這一點,但並不是每個功能都可以這樣轉換。