你如何将选项转换为无?

时间:2015-12-01 10:00:27

标签: scala monads optional

考虑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结果为null。我想要这样的目标同样处理数据库中没有匹配。如何将Some(null)转换为None

4 个答案:

答案 0 :(得分:3)

您可以使用filter

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

答案 1 :(得分:2)

通常,如果您想将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传递给它,它将返回None,这就是flatMap位的工作方式。

答案 2 :(得分:1)

向上做日期,我最好的匹配是使用flatMap

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

答案 3 :(得分:0)

致电map.get(1)将返回Some(ref(null))。执行Some(ref(null)) map (_.target)会导致Some(null)。这就是你得到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)