【问题标题】:Avoid null check correctly正确避免空检查
【发布时间】:2014-01-19 11:29:44
【问题描述】:

我正在尝试构建通用 for 循环。每个函数,如 func1、func2、func3 都可能返回 Some 或 None。

def func1(in: Option[String]): Option[String] = {
  return in
}

def func2(in: Option[String]): Option[String] = {
  return in
}

def func3(in: Option[String]): Option[String] = {
  return in
}


val res = for {
  x <- List(Some("hello"), None, Some("world"))
  y <- func1(x)
  z <- func2(y)
  w <- func3(z)
} yield w

print(res)

目的是完全避免空检查。

但以下错误不允许我将参数传递给第一次调用

 found   : String
 required: Option[String]
  z <- func2(y)
             ^
one error found
  1. 构建这样的链的正确方法是什么?

  2. 如何避免在我的函数中保留 Option[String] 参数。我想直接用字符串操作。

【问题讨论】:

    标签: scala for-loop null nullpointerexception monads


    【解决方案1】:

    Option trait aka Maybe Monad 倾向于与x =&gt; Option[y] 类型的函数一起使用。 for( &lt;- ) yield 语法糖被编译器替换为对应的 flatMap 调用,这相当于一元 bind 运算符。

    因此,您应该在flatMap 中使用X =&gt; M[Y] 之类的函数,并在Lists\ Options\ Streams \ Iterators 等中使用for-expression。

    阅读更多here

    您的第一个表达式的类型也是List[Option[X]]。要正确提取值,您可以在Vladimir's answer 中使用中间值。

    喜欢

    def func1(in: String): Option[String] = {
      Some(in)
    }
    
    def func2(in: String): Option[String] = {
      Some(in)
    }
    
    def func3(in: String): Option[String] = {
      Some(in)
    }
    
    
    val res = for {
      x <- List(Some("hello"), None, Some("world"))
      t <- x
      y <- func1(t)
      z <- func2(y)
      w <- func3(z)
    } yield w
    
    print(res)
    

    【讨论】:

      【解决方案2】:

      错误说明了这一点 - 您不需要将 funcX 参数设为 Option[String]。只使用String:

      def func1(in: String): Option[String] = {
        Some(in)
      }
      
      def func2(in: String): Option[String] = {
        Some(in)
      }
      
      def func3(in: String): Option[String] = {
        Some(in)
      }
      
      
      val res = for {
        x <- List(Some("hello"), None, Some("world"))
        y <- func1(x)
        z <- func2(y)
        w <- func3(z)
      } yield w
      
      print(res)
      

      【讨论】:

      • 已经试过了,会报错:在func1调用中输入mismatch; found: Option[String] required: String
      • @tmporaries,啊,是的,我不知道ListOptions 组成...... Odomontois 的答案是正确的。
      猜你喜欢
      • 1970-01-01
      • 2013-07-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-07
      • 1970-01-01
      • 2016-12-01
      • 1970-01-01
      • 2016-07-02
      相关资源
      最近更新 更多