为什么Some(1).getOrElse(Some(1))不是Option [Int]类型?

Sil*_*ust 8 scala

我目前正在使用Scala开发一个项目,似乎我并不完全理解Scala的类型系统: - /

我有以下情况:

def reviews(id: Int) = Action { implicit request =>
  Ok(html.products.reviews(
    reviewlist,
    reviewlist
      .find(review => review.id == id)
      .getOrElse(reviewlist.headOption)
  ))
}
Run Code Online (Sandbox Code Playgroud)

不幸的是编译器说,他无法将Product转换为Option [Review],所以我更改了代码

reviewlist
  .find(review => review.id == id)
  .getOrElse(reviewlist.headOption)
Run Code Online (Sandbox Code Playgroud)

id match {
  case 0 => reviewlist.headOption
  case id => reviewlist.find(review => review.id == id)
}
Run Code Online (Sandbox Code Playgroud)

这似乎现在有效,即使它与它不完全相同,例如,如果提交的评论ID无效,则不再显示第一条记录.然后会假装,还没有评论.

然后我将问题分解为一个简单的样本:

val a: Option[Int] = Some(1).getOrElse(Some(1))
Run Code Online (Sandbox Code Playgroud)

那么,有谁有想法,为什么右侧的表达式不是Option [Int]类型?两者,Some(1)和None都直接从Option继承而且这个表达式实际上是Some(1)in any或者我错了吗?

有趣的是

val a: Option[Int] = None.getOrElse(None)
Run Code Online (Sandbox Code Playgroud)

工作,但所有其他组合不...

om-*_*nom 14

你自找的:

val a: Option[Int] = Some(1).orElse(Some(1))
Run Code Online (Sandbox Code Playgroud)

因为

x.getOrElse(y)
Run Code Online (Sandbox Code Playgroud)

将返回1,如果x是Some(1)y(这是Some(1))如果x是None,或者在代码地讲:

if (Some(1).isDefined) 1 else Some(1)
Run Code Online (Sandbox Code Playgroud)

  • @pelotom它只是[不是真的](http://stackoverflow.com/q/14305308/298389) (2认同)

bra*_*don 8

类型签名Option.getOrElse

getOrElse[B >: A](default: ? B): B
Run Code Online (Sandbox Code Playgroud)

这意味着,当你调用getOrElseOption[A],它会试图返回您类型的东西A.如果default(B)的类型不相同A,它将寻找最接近的共享祖先AB.根据你的情况,A并且BOption[Int]Int.编译器可以做的最好的是Any.