以下Java“继续”代码如何转换为Scala?

时间:2011-07-17 02:38:52

标签: scala

for (String stock : allStocks) {

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

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

}

我不一定需要逐行翻译,但我正在寻找“Scala方式”来处理这类问题。

5 个答案:

答案 0 :(得分:28)

在这样的情况下,你不需要继续或易碎或类似的东西:选项和理解很好地完成了这个技巧,

val stocksWithPrices =
  for {
    stock <- allStocks
    quote <- Option(getQuote(...))
    price <- Option(quote.getPrice())
  } yield (stock, quote, price);

答案 1 :(得分:9)

通常,您会尝试在开始之前通过过滤来避免这些情况:

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构造指定了中断应该到达的位置。如果你在for循环之外放置breakable,它就像标准的Java风格中断一样。如果你把它放在里面,它就像continue

当然,如果您的条件非常少,则根本不需要继续;只需使用if语句的else。

答案 2 :(得分:7)

此处的控制结构可以非常惯用地映射到以下for循环中,您的代码演示了Scala的for循环的设计过滤类型。

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

顺便说一句,Scala会自动将其解析为Rex Kerr解决方案的代码

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 :(得分:3)

如果重点确实放在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)
}

答案 4 :(得分:1)

最简单的方法是将跳过的代码嵌入到if中,并具有反转意义。

请参阅http://www.scala-lang.org/node/257