我想这个代码片段返回我None
,而不是Some(null)
:Option.map(空)返回一些(空)
Option(x).map(x.getNullValue) // returns Some(null)
听说Scalaz
图书馆功能来处理这种情况。那么我怎样才能实现我的目标:scalaz
和标准的Scala库?
我想这个代码片段返回我None
,而不是Some(null)
:Option.map(空)返回一些(空)
Option(x).map(x.getNullValue) // returns Some(null)
听说Scalaz
图书馆功能来处理这种情况。那么我怎样才能实现我的目标:scalaz
和标准的Scala库?
你可以与Option.apply
方法一起使用flatMap
这里,而不是在scalaz
拉:
Option(initialValue).flatMap(x => Option(x.getNullValue))
这工作,因为Option.apply
方法踹null
智能:
val x: String = null
Option(x) //None
Option("foo") //Some("foo")
所以,如果你知道值直接,你可以简单地做:
Option(x.getNullValue)
您也可以使用其他方法对Option
像filter
,orElse
,或getOrElse
,根据不同的情况:
Option(initialValue).map(_.getNullValue).filter(_ != null)
Option(initialValue).orElse(Option(x.getNullValue))
Option(x.getNullValue).getOrElse(defaultValue)
我不知道scalaz,但在标准库中你唯一的选择真的是过滤掉null
值。 map
只是映射A => B
,并且期望B
不会是null
。
例子:
object HasNull {
def getNull: Any = null
}
scala> Option(HasNull).map(_.getNull).filter(_ != null)
res24: Option[Any] = None
或者
scala> Option(HasNull).flatMap(a => Option(a.getNull))
res25: Option[Any] = None
或者,你可以使用一个小隐魔避免Option
样板:
implicit def toOpt[A](a: A): Option[A] = Option(a)
scala> Option(HasNull).flatMap(_.getNull)
res3: Option[Any] = None
使用flatMap
仍是关键,因为它期望Option[B]
。但getNull
的类型为B
,因此将使用隐式转换,它将再次将可空对象包含在Option.apply
中。
正如其他人已经写了,你可以使用flatMap来做到这一点。和一个非常类似的方法是:
case class User(name: String)
val users = List(null, User("John"), User(null))
for{
userDb <- users
user <- Option(userDb)
name <- Option(user.name)
} yield name
与None
的问题是,你不知道哪个None
您将获得:用户不存在或名称?在这种情况下,scalaz可以帮助你:
for{
userDb <- users
user <- Option(userDb) \/> "No user found."
name <- Option(user.name) \/> "No name provided."
} yield name
'Option(x.getNullValue)'有什么问题? – ipoteka
@ipoteka'x'也可以为null,所以我也把它换成'Option' – MyTitle