Примечание: @ Ответ Алексея Романова, приведенный ниже, является правильным. Я обновил этот ответ, чтобы включить более глубокую и правильную информацию.
Опция, некоторые и None
Вы можете лучше понять, как Option
работает с более простым примером. Здесь, Option
, что на самом деле None
проходит первый случай и улавливается только на втором уровне:
val foo: Option[String] = None
foo match {
case x: Option[String] => "Yep! It's an option!"
case None => "Foo is None!"
} // res0: String = Yep! It's an option!
Поскольку None
на самом деле подкласс Option
, значение None
будет соответствовать Option[String]
. Правильное решение заключается в использовании Some(String)
:
foo match {
case Some(String) => "It's a string!"
case None => "Foo is None!"
} // res0: String = Foo is None!
это только фон, но: кажется, у вас есть вложенная Option
:
scala.None $ не может быть приведен к com.fredley.Edit
Это указывает на то, что оба pending
и published
не None
, и действительно Option[<something>]
, но из-за типа стиранием матч не диффере tiate. Например:
val foo: Option[String] = None
val bar: Option[String] = Option("fubar")
for (x <- List(foo, bar)) x match {
case x: Option[Int] => println(s"It's a string=$x")
case None => println(s"It is None!")
case _ => println("No match found.")
}
Даже если это не должно соответствовать Option[Int]
, выше будет печатать:
It's a string=None
It's a string=Some(fubar)
Примечание на условные переменные
В то время как вы можете вставлять свои условные операторы, как вы сейчас , совпадение случаев позволяет включить их в сам корпус:
val suspended = true
foo match {
case x: Some[String] => "It's a string!"
case None if suspended => "None but suspended!"
case None => "Foo is None!"
} // res0: String = None but suspended!
Таким образом, вы можете преобразовать ваш код:
def getStatus: MyStatus = {
(mPending, mPublished) match {
case (None, None) => MyStatus.inactive
case (Some(Edit), None) => MyStatus.neverPublished
case (None, Some(Edit)) if published.get.isSuspended => MyStatus.suspended
case (None, Some(Edit)) => MyStatus.published
case (_, Some(published)) if published.get.isSuspended => MyStatus.suspendedWithChanges // We don't care about the first param, so use _, let the compiler determine the type of `published`.
case (_, Some(published)) => MyStatus.publishedWithChanges
}
}
Это может или не может быть проще для вас, чтобы разобрать, но это вариант, если вы найти условное ветвление, становится непрозрачным.
Вы создаете тип, попробуйте удалить часть ': Option [Edit]', возможно, вы не получаете тип, который вы ожидаете, если эти переменные являются параметрами в вашем совпадении, должно быть 'None' и 'Some (value)', если у вас нет опции. Для исключения это происходит при получении из-за того, что вы соответствуете 'Option [Edit]', но 'None' является допустимым для этого типа. –
Чтобы перефразировать Ende Neu, используйте 'Some (edit: Edit)', чтобы извлечь непустую опцию. Но странный CCE предполагает, что у вас есть вложенный вариант. –
Является ли 'MyStatus' псевдоним' (опция [Edit], Option [Edit]) => Something'? – pedrofurla