Czy jest jakiś prawdziwy powód dostarczenia oświadczenia return
w Scala? (oprócz bycia bardziej "przyjaznym dla Javy")Cel oświadczenia "Zwrot" w Scali?
Odpowiedz
Ignorując zagnieżdżone funkcje, zawsze można zamienić obliczenia Scala na zwroty z równoważnymi obliczeniami bez zwracanych danych. Wynik ten sięga początków "programowania strukturalnego" i nazywa się on sprytnie.
W przypadku funkcji zagnieżdżonych sytuacja ulega zmianie. Scala pozwala umieścić "powrót" głęboko w szeregu funkcji zagnieżdżonych. Po wykonaniu return, kontrola przeskakuje ze wszystkich zagnieżdżonych funkcji do najbardziej wewnętrznej metody, z której się zwraca (zakładając, że metoda nadal jest wykonywana, w przeciwnym razie zostanie zgłoszony wyjątek). Tego rodzaju rozwijanie stosu może odbywać się z wyjątkami, ale nie można tego zrobić poprzez mechaniczną restrukturyzację obliczeń (jak to jest możliwe bez funkcji zagnieżdżonych).
Najczęstszym powodem, dla którego rzeczywiście chciałbyś powrócić z funkcji zagnieżdżonej, jest przełamanie imperatywu dla zrozumienia lub blokady zasobów. (Ciało imperatyw dla-pojmowania zostanie przetłumaczony na zagnieżdżonej funkcji, mimo że wygląda jak oświadczeniu.)
for(i<- 1 to bezillion; j <- i to bezillion+6){
if(expensiveCalculation(i, j)){
return otherExpensiveCalculation(i, j)
}
withExpensiveResource(urlForExpensiveResource){ resource =>
// do a bunch of stuff
if(done) return
//do a bunch of other stuff
if(reallyDoneThisTime) return
//final batch of stuff
}
Dostarcza się w celu dostosowania do tych okoliczności, w których utrudnione lub uciążliwe jest ustalenie wszystkich ścieżek przepływu sterowania w celu zejścia na leksykalny koniec metody.
Chociaż z pewnością jest tak, jak mówi Dave Griffith, że można wyeliminować jakiekolwiek użycie return
, często może to być bardziej zaciemnione, niż proste obcięcie skrótu wykonawczego z widocznym return
.
Należy również pamiętać, że return
powraca z metod, a nie z funkcji (literałów), które można zdefiniować w ramach metody.
Wiedziałem, że to była odpowiedź .. Po prostu nie mogę wymyślić żadnych przykładów. – Jus12
Na szczęście dla mnie nie prosiłeś o żadne przykłady ... –
+1 za zaciemnienie –
wyświetlić return
jako przydatny przy pisaniu nadrzędny kod styl, który zazwyczaj oznacza, że / Kod O. Jeśli robisz czysty kod funkcjonalny, nie potrzebujesz (i nie powinieneś używać) return
. Ale dzięki funkcjonalnemu kodowi możesz potrzebować lenistwa, aby uzyskać wydajność równoważną z imperatywnym kodem, który może "uciec wcześniej" z użyciem return
.
Oto przykład
Ta metoda ma wiele if-else do sterowania przepływem, ponieważ nie ma powrotu (czyli to, co ja przyszedłem z, można użyć wyobraźni, aby go przedłużyć). Wziąłem to z prawdziwym przykład życia i modyfikowane to być kod manekina (w rzeczywistości jest on dłuższy niż to):
Bez powrotu:
def process(request: Request[RawBuffer]): Result = {
if (condition1) {
error()
} else {
val condition2 = doSomethingElse()
if (!condition2) {
error()
} else {
val reply = doAnotherThing()
if (reply == null) {
Logger.warn("Receipt is null. Send bad request")
BadRequest("Coudln't receive receipt")
} else {
reply.hede = initializeHede()
if (reply.hede.isGood) {
success()
} else {
error()
}
}
}
}
}
ze zwrotem:
def process(request: Request[RawBuffer]): Result = {
if (condition1) {
return error()
}
val condition2 = doSomethingElse()
if (!condition2) {
return error()
}
val reply = doAnotherThing()
if (reply == null) {
Logger.warn("Receipt is null. Send bad request")
return BadRequest("Coudln't receive receipt")
}
reply.hede = initializeHede()
if (reply.hede.isGood)
return success()
return error()
}
W moich oczach ten drugi jest bardziej czytelny, a nawet łatwiejszy w zarządzaniu niż pierwszy. Głębokość wcięcia (z dobrze sformatowanym kodem) idzie głęboko i głęboko, jeśli nie używasz instrukcji return. I nie podoba mi się to :)
Myślę, że dobrze wytrawni programiści Scala (nie ja) mogą lepiej śledzić pierwszy fragment. – Jus12
Rzeczywiście jest to trochę "smaku", zależy od deweloperów punktu widzenia. na przykład Najbardziej podobają mi się płaskie – yerlilbilgin
- 1. oświadczenia przełącznika w Prologu
- 2. Zwrot nie w funkcji
- 3. Zwrot pustki?
- 4. Zwrot jstring w programie JNI
- 5. UICollectionReusableView - Brakujący zwrot w funkcji
- 6. Implementacja oświadczenia majątkowego
- 7. 800A0401 - Oczekiwany koniec oświadczenia
- 8. mysql trwale przygotowane oświadczenia
- 9. PDO Przygotowane oświadczenia - NULLs
- 10. SQL - według oświadczenia
- 11. warunkowe Oświadczenia różnica
- 12. mysqli_real_escape_string Oświadczenia przygotowane?
- 13. Nieoczekiwany zwrot (LocalJumpError)
- 14. Zwrot pustej obietnicy
- 15. Jak zaimplementować transformator monadowy `List` w Scali?
- 16. Oświadczenia po END w procedurze przechowywanej
- 17. R lśniące warunkowe oświadczenia w studiu
- 18. Priorytet w obejściu oświadczenia Go select
- 19. Kompilacja warunkowa w Scali
- 20. Inicjowanie tablic w Scali
- 21. Implementacja ExpandoObject w Scali
- 22. Zagnieżdżona iteracja w Scali
- 23. Parametry "Spread" w Scali?
- 24. Operator tyldy w Scali
- 25. Algorytm Kadane'a w Scali
- 26. Drukowanie tablicy w Scali
- 27. Rodzinny polimorfizm w Scali
- 28. Relacje równości w Scali
- 29. Dystrybucja Scali w klastrze?
- 30. Powtarzanie listy w Scali
Dzięki za odpowiedź.Jest to bardzo pouczające. – Jus12
Myślę, że jest to bardziej formalna odpowiedź. Jestem zainteresowany dowodem wyniku, o którym wspomniałeś. Czy możesz podać referencje? – Jus12
Dodano link do wikipedii dla twierdzenia o programie strukturalnym. –