2014-10-31 13 views
5

Uczę się Scali i zauważyłem coś o używaniu zwrotu.Jaka jest różnica między używaniem instrukcji return a domyślnym zwracaniem ostatniej wartości?

Tak, oczywiście w Scala, jeśli nie posiada instrukcji return, ostatnia wartość jest zwracana domyślnie. Który jest świetny. Ale jeśli używasz instrukcji return bez określenia typu zwracanej, Scala mówi "error: method testMethod has return statement; needs result type"

Tak to działa

def testMethod(arg: Int) = { 
    arg*2 
    } 

ale daje to błąd

def testMethod(arg: Int) = { 
    return arg*2 
    } 

To sprawia mi podrapać brodę i przejść

Mmmmmmmm ... Musi być ku temu powód.

Dlaczego deklaracja typu jawnego jest potrzebna, gdy używasz instrukcji return, ale nie wtedy, gdy pozwalasz Scali zwracać ostatnią wartość? Zakładam, że są dokładnie tym samym, a instrukcje return są przeznaczone tylko dla tego, jeśli chcesz zwrócić wartość wewnątrz funkcji zagnieżdżonej/warunkowej, itd. (Innymi słowy, instrukcja "return" jest automatycznie wstawiana do ostatniej wartości przez kompilator .. jeśli nie przedstawi nigdzie indziej w metodzie)

ale wyraźnie myliłem. Z pewnością musi być jakaś inna różnica w realizacji?

Czy brakuje mi czegoś?

+0

Wyobrażałem to nie kompiluje ponieważ jesteś rzeczywiście użyciu słowa kluczowego 'return' i Miałem rację. Opublikuję odpowiedź w ciągu sekundy. Zasadniczo, jeśli użyjesz return, będziesz szukał tego, że zadeklarowałeś zwracany typ zamiast samodzielnie określać typ zwracany. – Luminous

Odpowiedz

4

Jeśli masz wiele punktów wyjścia ze swojej metody, kompilator może nie mieć możliwości określenia typu zwrotu. Jedynym sposobem uzyskania wielu punktów wyjścia ze swojej metody jest użycie wielu s. return. (Lub jeden return plus niejawny zwrot).

Ponieważ zasady, kiedy działają, a kiedy nie, są dość złożone, może to wyglądać na użytkownika, że ​​czasami działa losowo, a czasami nie. Po prostu zabronione wnioskowanie typu w ogóle w obecności wyraźnej return jest znacznie prostszą regułą, nawet jeśli jest nieco restrykcyjna.

1

To pytanie było "When is a return type required for methods in Scala?" Inna kwestia całkowicie, ale to w tej samej dziedzinie, jak OP.


Ta odpowiedź wyjaśnia, kiedy (dlaczego nie) trzeba dać mu Zwraca typ:

https://stackoverflow.com/a/3127260/2567273

Chapter 2. Type Less, Do More książki Programming Scala mowa o:

Gdy wymagane są adnotacje typu Explicit Type.

Z praktycznego punktu widzenia, trzeba zapewnić wyraźne adnotacje typu w następujących sytuacjach:

wartości zwracanych metoda w następujących przypadkach:

  • Gdy jawnie wywołać zwrot w sposobie (nawet przy koniec).
  • Gdy metoda jest rekurencyjna.
  • Gdy metoda jest przeciążona i jedna z metod wywołuje inną. Metoda wywołująca wymaga adnotacji typu zwrotu.
  • Gdy wywnioskować typ zwracany byłby bardziej ogólny niż zamierzony, np Any.

To nie wyjaśnia, dlaczego trzeba określić zwrot (tylko kiedy), ale będę trzymać się tego, co powiedziałem w moim komentarzu. Powodem, dla którego musisz określić typ zwracany podczas używania słowa kluczowego return, jest to, że kompilator będzie szukał tego, co dałeś mu typem zwracania, lub też sam wywnioskuje typ zwracania, tak jakbyś nie używał return w ogóle. Jeśli używasz konkretnie return, pomagasz kompilatorowi, mówiąc mu, co powrócić, a następnie oczekuje, że powiesz mu, jaki typ powracasz.

+0

Nie jestem pewien, czy uzasadnienie ma sens. – acjay

+0

Z POV kompilatora myślę, że tak. Czasami sytuacja jest zbyt skomplikowana, aby można było wywnioskować, jaki jest typ zwrotu. Jeśli nie, musisz to powiedzieć. Nawet w podstawowych sytuacjach, takich jak przykład OP, użycie 'return' tworzy kontrakt inicjujący, który również powiesz typowi powrotu. Ja tylko rzucam tę odpowiedź, biorąc pod uwagę to, co wiem z mojej klasy kompilatorów. Nie jestem programistą scala. – Luminous

+0

Byłby to trywialny krok kompilatora, aby usunąć niepotrzebny końcowy "powrót" z AST. Myślę więc, że dokładniej byłoby powiedzieć (podobnie jak w przypadku innej odpowiedzi), że wybrali spójność reguł z wczesnym 'return' - jedynym niezbędnym użyciem' return' - nadmiernym wnioskiem o niepotrzebny "powrót" . – acjay

1

Co sądzisz powinna typu wnioskowanie zaznaczyć powrocie typ jak:

def func(n:Int) = { 
    if(n<10) return 23; 
    if(n>10) true else false; 
} 

Pierwsza linia sugeruje, zwracana wartość powinna być typu Int. Ale ukryty powrót sugeruje wartość boolowską. Tak więc staje się to dość dyskusyjne na temat tego, jaki dokładnie powinien być typ zwrotu. Int, Boolean lub Any?

W przypadku, gdy nie zastosowano wyraźnego zwrotu, bardzo proste jest określenie typu zwrotu funkcji. Ale wraz z nim jest nieco niejasny i nieznany. Najprostszym rozwiązaniem byłoby jawne określenie typu zwracanego przez użytkownika. To znacznie ułatwia życie kompilatorowi.

Ponadto zespół chciał zniechęcić użycie wyraźnych typów zwrotnych, dzięki czemu ludzie tak umieścić ręcznych typy idzie z zamiarem :)

Powiązane problemy