2015-03-07 7 views
4

Есть ли хороший способ получить доступ к значению параметра внутри объекта Option? Вложенные примеры матчей приводят к уродливой древовидной структуре.Scala: доступ к необязательному значению в необязательном объекте

Так что, если у меня есть, например:

case class MyObject(value: Option[Int]) 
val optionObject : Option[MyObject] = Some(MyObject(Some(2)) 

Единственный способ я знаю, чтобы получить доступ к значению будет:

val defaultCase = 0 //represents the value when either of the two is None 
optionObject match { 
    case Some(o) => o.value match { 
     case Some(number) => number 
     case None => defaultCase 
    } 
    case None => defaultCase 
} 

И это довольно уродлив, как эта конструкция только для доступа к одному небольшое значение параметра.

То, что я хотел бы сделать что-то вроде:

optionObject.value.getOrElse(0) 

или, как вы можете сделать с Swift:

if (val someVal = optionObject.value) { 
    //if the value is something you can access it via someVal here 
} 

Есть ли что-то в Scala, что позволяет мне обрабатывать эти вещи хорошо?

Спасибо!

ответ

6

flatMap позволит вам отобразить опцию и «сгладить» результат. Поэтому, если (и только если) внешний и внутренний Option оба являются Some, вы получите Some с вашей стоимостью. Затем вы можете позвонить getOrElse, как и с любым другим Option.

optionObject.flatMap(_.value).getOrElse(0) 
+0

Очень хорошо, но если вложенность глубже она будет расширяться: (. _ SomeOther) '' 'optionObject.flatMap (. _ Значение) .flatMap .flatMap (. _ Другой) .getOrElse (0) '' '' право? Это лучше, чем вложенное совпадение, но может быть применен небольшой синтаксический сахар. – lukaswelte

+2

Для понимания полезно: 'val v: Option [String] = для {someVal1 <- opt1; val2 <- someVal1.optProp; val3 <- val2.optProp} yield val3' – cchantep

+0

Я думал о понимании, но в этом случае они просто делают код вдвое длиннее ... –