【问题标题】:How to yield None in for-comprehension if some condition meets如果满足某些条件,如何在理解中产生 None
【发布时间】:2018-06-12 15:01:25
【问题描述】:

我正在尝试理解并编写了以下代码:

object Main extends App {
    val resultOption: Option[Int] = 
    for{
        i1 <- opt1
        i2 <- opt2
    } yield {
        if(i1 + i2 > 10) null.asInstanceOf[Int]
        else i1 + i2
    }

    println(resultOption) // <---- Here

    def opt1: Option[Int] = //some computations
    def opt2: Option[Int] = //some computations
}

IDEONE working example

我希望 resultOption 成为 None 以防满足条件,但返回了 Some(0)。我查看了 yield 块的编译代码,我们这里有:

Code:
   0: aload_0
   1: getfield      #25                 // Field i1$1:I
   4: iload_1
   5: iadd
   6: bipush        10
   8: if_icmple     18
  11: aconst_null
  12: invokestatic  #31                 // Method scala/runtime/BoxesRunTime.unboxToInt:(Ljava/lang/Object;)I
  15: goto          24
  18: aload_0
  19: getfield      #25                 // Field i1$1:I
  22: iload_1
  23: iadd
  24: ireturn

12:,我们调用BoxesRunTime.unboxToInt(null),它确实返回0。问题是在i1 + i2 &gt; 10 的情况下如何产生None

【问题讨论】:

    标签: scala for-comprehension scala-option


    【解决方案1】:

    仅从asInstanceOf-codesmell 就应该很明显它不能那样工作。您必须将过滤步骤移至for-表达式的生成器部分:

    for{
        i1 <- opt1
        i2 <- opt2
        if (i1 + i2 <= 10)
    } yield i1 + i2
    

    请注意,在for-comprehension 中,(i1 + i2 &lt;= 10) 中的括号可以省略。

    【讨论】:

      猜你喜欢
      • 2018-01-09
      • 1970-01-01
      • 2017-07-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-12
      • 2020-12-06
      相关资源
      最近更新 更多