如何将选项转换为 None?

How do you convert option to None?

考虑example

object Main extends App {
  case class ref(val target: Object)
  val map: Map[Int, ref] = Map(1 -> ref(null), 2 -> ref("2")) 
                                            //> map  : Map[Int,o.ref] = Map(1 -> ref(null), 2 -> ref(2))

  def request(id: Int, default: Object) = {
    println(map.get(id) map (_.target) match {
      case Some(result) => result
      case None => default
    })
  }                                         //> request: (id: Int, default: Object)Unit
  request(0, "fixed 0")                     //> fixed 0
  request(1, "fixed 1")                     //> null
  request(2, "fixed 2")                     //> 2
}

如您所见,option1 结果为空。我希望这样的目标能够处理,同样在数据库中没有匹配项。如何将 Some(null) 转换为 None

到目前为止,我最喜欢的是使用 flatMap

map (_.target) flatMap { case null => None ; case a => Some(a) } 

调用 map.get(1) 将 return Some(ref(null))。执行 Some(ref(null)) map (_.target) 结果是 Some(null)。这就是为什么你得到空值。您可以这样做:

def request(id: Int, default: Object) = {
    println(map.get(id).flatMap(r => Option(r.target)).getOrElse(default))
}

现在 request(1, "fixed 1") 将打印 fixed 1.

此外,您最后的 match 表达式可以缩短为 getOrElse(default)

您可以使用 filter:

map (_.target) filter (_ != null)

一般来说,如果你想将可能是 null 的值转换为 Option,只需像这样构建它:

Option(ref)

在您的情况下,由于您希望内部字段成为 Option,您可以 flatMap:

map.get(id).flatMap(ref => Option(ref.target))

我会重写你的 request 方法:

def request(id: Int, default: Object) =
  println(map.get(id).flatMap(ref => Option(ref.target)).getOrElse(default))

Option的apply方法就是你想要的,如果你传给它一个null,它就会return一个None,就是这样flatMap 位有效。