for (String stock : allStocks) {
Quote quote = getQuote(...);
if (null == quoteLast) {
continue;
}
Price price = quote.getPrice();
if (null == price) {
continue;
}
}
我不一定需要逐行翻译,但我正在寻找"Scala方式“来处理这种类型的问题。
发布于 2011-07-17 17:15:12
在这样的情况下,你不需要continue或trick或任何类似的东西: Options和for comprehensions做得很好,
val stocksWithPrices =
for {
stock <- allStocks
quote <- Option(getQuote(...))
price <- Option(quote.getPrice())
} yield (stock, quote, price);
发布于 2011-07-17 10:48:29
通常,您可以在开始之前进行过滤,以避免出现这些情况:
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风格的break。如果你把它放在里面,它的行为就像continue
。
当然,如果条件数量非常少,则根本不需要continue;只需使用if语句的else即可。
发布于 2011-07-17 11:33:17
在这里,您的控制结构可以非常地道地映射到下面的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
的所有不同类型的更复杂的流,但它确实解决了许多常见的问题。
https://stackoverflow.com/questions/6721594
复制相似问题