比较Option [T]的实例,避免None == None

Sot*_*ric 10 scala

昨天我突然明白了,并了解人们如何以及为什么人们使用'map'方法和Option来比较值.是的,我有点慢,抱歉:)

我修改了这些非常好的链接,并提出了我想问的问题.

http://twitter.github.com/effectivescala

http://blog.tmorris.net/posts/scalaoption-cheat-sheet

在我的Lift webapp中,我有一些Option [User]和Option [Server]变量.我试图通过以下检查找出此用户是否是此服务器的管理员

if(user.map(_.id) == server.map(_.adminId))
Run Code Online (Sandbox Code Playgroud)

但是我注意到,如果'user'是None而'server'也是None,那么这个检查成功,这对我不利(如果它们中的任何一个是None,我希望这个检查失败).我可以添加user.isDefined条件,但我觉得有更多正确的方法来做到这一点.你能告诉我如何用Scala方式完成它吗?

Rég*_*les 21

你可以用模式匹配(在这种情况下可能是最清晰的方式)来做到这一点:

(user, server) match {
  case (Some(user), Some(server)) if user.id == server.adminId =>
    // both ids are matching, handle this case here
  case _ =>
    // no match, handle this case here
}
Run Code Online (Sandbox Code Playgroud)

你也可以尝试作为一个单行,但在这里我不建议它,因为它是非常混淆:

if ( user.flatMap{ user => server.map(_.adminId == user.id) }.getOrElse( false ) ) {
  // both ids are matching, handle this case here
}
else {
  // no match, handle this case here
}
Run Code Online (Sandbox Code Playgroud)

最后,如果你只需要处理id匹配的情况(如果没有则只会做什么),使用for comprehension对于一个选项来说并不是太糟糕(没有双关语):

for ( user <- user; server <- server if user.id == server.adminId ) {
  // both ids are matching, handle this case here
}
Run Code Online (Sandbox Code Playgroud)

  • 单行可以简化一下:`user.exists(u => server.exists(_.adminId == u.id))` (3认同)

Sum*_*uma 9

为此,我习惯了exists/ 的组合contains.

比较相同类型的两个选项时:

o1.exists(o2.contains)
Run Code Online (Sandbox Code Playgroud)

在您的情况下,这可以使用map:

user.map(_.id).exists(server.map(_.adminId).contains)
Run Code Online (Sandbox Code Playgroud)