Как следующий код Java "continue" переводит в Scala? - PullRequest
15 голосов
/ 17 июля 2011
for (String stock : allStocks) {

    Quote quote = getQuote(...);
    if (null == quoteLast) {
        continue;
    }

    Price price = quote.getPrice();
    if (null == price) {
        continue;
    }

}

Мне не обязательно переводить построчно, но я ищу "способ Scala" для решения этого типа проблем.

Ответы [ 5 ]

28 голосов
/ 17 июля 2011

Вам не нужно продолжать или прерывать или что-то подобное в таких случаях: Опции и для понимания прекрасно справляются с задачей,

val stocksWithPrices =
  for {
    stock <- allStocks
    quote <- Option(getQuote(...))
    price <- Option(quote.getPrice())
  } yield (stock, quote, price);
9 голосов
/ 17 июля 2011

Как правило, вы пытаетесь избежать таких ситуаций, начиная с фильтрации, прежде чем даже начинать:

val goodStocks = allStocks.view.
  map(stock => (stock, stock.getQuote)).filter(_._2 != null).
  map { case (stock, quote) => (stock,quote, quote.getPrice) }.filter(_._3 != null)

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

На самом деле, у вас, вероятно, есть кавычки и такие параметры возврата - смотритев StackOverflow приведены примеры того, как использовать их вместо возвращаемых значений NULL.

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

import scala.util.control.Breaks._
for (stock <- allStocks) {
  breakable {
    val quote = getQuote(...)
    if (quoteLast eq null) break;
    ...
  }
}

Конструкция breakable указывает, куда вас должны привести разрывы.Если вы помещаете breakable вне цикла for, он работает как стандартный разрыв в стиле Java.Если вы поместите его внутрь, он будет действовать как continue.

Конечно, если у вас очень мало условий, вам вообще не нужно продолжать;просто используйте остальную часть оператора if.

7 голосов
/ 17 июля 2011

Ваша структура управления здесь может быть очень идиоматически отображена в следующем цикле for, и ваш код демонстрирует тип фильтрации, для которой был разработан цикл for в Scala.

for {stock <- allStocks.view
     quote = getQuote(...)
     if quoteLast != null
     price = quote.getPrice
     if null != price
    }{
      // whatever comes after all of the null tests
    }

Кстати, Scala автоматически выведет это в код из решения Рекса Керра

val goodStocks = allStocks.view.
  map(stock => (stock, stock.getQuote)).filter(_._2 != null).
  map { case (stock, quote) => (stock,quote, quote.getPrice) }.filter(_._3 != null)

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

3 голосов
/ 17 июля 2011

Если фокус действительно на continue, а не на обработке null, просто определите внутренний метод (часть обработки null - это другая идиома в scala):

def handleStock(stock: String): Unit {
  val quote = getQuote(...)
  if (null == quoteLast) {
    return
  }

  val price = quote.getPrice();
  if (null == price) {
    return
  }
}

for (stock <- allStocks) {
  handleStock(stock)
}
1 голос
/ 17 июля 2011

Самый простой способ - встроить пропущенный код в if с обратным смыслом к ​​тому, что у вас есть.

См. http://www.scala -lang.org / node / 257

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...