2010-09-22 5 views

ответ

47

Игнорирование вложенных функций всегда позволяет заменить вычисления Scala с помощью эквивалентных вычислений без возврата. Этот результат восходит к ранним дням «структурированного программирования» и назван structured program theorem, достаточно умно.

С вложенными функциями ситуация меняется. Scala позволяет размещать «возврат» в глубину внутри серии вложенных функций. Когда возврат выполняется, управление выпрыгивает из всех вложенных функций в самый внутренний содержащий метод, из которого он возвращается (при условии, что метод на самом деле все еще выполняется, в противном случае создается исключение). Такой тип разворачивания стека может быть выполнен с исключениями, но не может быть выполнен путем механической перестройки вычисления (как это возможно без вложенных функций).

Наиболее распространенная причина, по которой вы действительно хотите вернуться изнутри вложенной функции, состоит в том, чтобы выйти из императивного для понимания или управления ресурсами блока. (Тело императива-осмыслению переводится на вложенную функцию, даже если она выглядит так же, как утверждение.)

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 
} 
+0

Спасибо за ответ.Это очень информативно. – Jus12

+0

Я думаю, что это более формальный ответ. Меня интересует доказательство упомянутого вами результата. Можете ли вы предоставить некоторые рекомендации? – Jus12

+0

Добавлена ​​ссылка на wikipedia для структурированной программной теоремы. –

26

Он предоставляется для того, чтобы приспособить те обстоятельства, при которых сложно или громоздко организовать все пути потока управления, чтобы сходиться на лексическом конце метода.

Хотя, по словам Дэйва Гриффита, вы можете устранить любое использование return, часто это может быть более запутанным, чем просто сократить сокращение короткого замыкания return.

Помните, что return возвращает методы, а не функции (литералы), которые могут быть определены в рамках метода.

+0

Я знал, что это был ответ. Я просто не могу придумать никаких примеров. – Jus12

+8

К счастью для меня, вы не просили каких-либо примеров ... –

+0

+1 для обфускатора –

2

Я рассматриваю return как полезно при написании императивного кода типа, который обычно означает, что I/Вывода. Если вы используете чистый функциональный код, вам не нужно (и не следует использовать) return. Но с функциональным кодом вам может понадобиться лень, чтобы получить производительность, эквивалентную императивному коду, который может «ускользнуть» с нуля, используя return.

3

Вот пример

Этот метод имеет много если-иначе заявления для управления потоком, потому что нет возврата (то есть то, что я пришел с, вы можете использовать свое воображение, чтобы расширить его). Я взял это из реального примера жизни и изменить его, чтобы быть фиктивный код (на самом деле это больше, чем это):

без возврата:

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() 
      } 
      } 
     } 
     } 
    } 

С возвращением:

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() 
    } 

На мой взгляд, второй является более читаемым и даже управляемым, чем первый. Глубина углубления (с хорошо отформатированным кодом) идет глубоко и глубоко, если вы не используете оператор return. И мне это не нравится :)

+2

Я думаю, что опытные программисты Scala (а не я) могут более четко следовать первому фрагменту. – Jus12

+0

Действительно, это немного «вкус», зависит от точки зрения разработчиков. например Мне нравится плоский – yerlilbilgin

Смежные вопросы