W przeciwieństwie do języków C# (oraz Java i C i C++), które są językami opartymi na instrukcjach, Scala jest językiem opartym na ekspresji. To głównie duży plus pod względem kompozycyjności i czytelności, ale w tym przypadku różnica cię ugodziła.
metoda A Scala niejawnie zwraca wartość ostatniego wyrażenia w metodzie
scala> def id(x : String) = x
id: (x: String)String
scala> id("hello")
res0: String = hello
w Scala prawie wszystko jest wyrażeniem. Rzeczy, które wyglądają jak instrukcje, są nadal wyrażeniami, które zwracają wartość typu o nazwie Jednostka. Wartość można zapisać jako().
scala> def foo() = while(false){}
foo:()Unit
scala> if (foo() ==()) "yes!" else "no"
res2: java.lang.String = yes!
Nie kompilator dla Turing-równoważnej języku można wykryć wszystkie non-zakończenia pętli (por Turing zatrzymanie problem) więc większość kompilatorów zrobić bardzo mało pracy, aby wykryć każdy. W tym przypadku typ "while (someCondition) {...}" jest jednostką bez względu na to, co jest pewne, nawet jeśli jest to stała prawda.
scala> def forever() = while(true){}
forever:()Unit
Scala stwierdzi, że zadeklarowany typ zwracany (String) nie jest zgodna z rzeczywistą typ zwracany (część), która jest rodzajem ostatniego wyrazu (gdy ...)
scala> def wtf() : String = while(true){}
<console>:5: error: type mismatch;
found : Unit
required: String
def wtf() : String = while(true){}
odpowiedzi: dodanie wyjątek na końcu
scala> def wtfOk() : String = {
| while(true){}
| error("seriously, wtf? how did I get here?")
| }
wtfOk:()String
FWIW - istnieją [ wiele sposobów ogólnej implementacji logiki powtórzeń] (http://stackoverflow.com/q/7930814/115478). – leedm777
+1 Dziękujemy za porady i więcej informacji na temat pułapek tailrec. –