web-dev-qa-db-ja.com

Scalaオプション-if(opt.isDefined){}を取り除く

私のコードは次のコードパターンで散らかっています:

val opt = somethingReturningAnOpt
if (opt.isDefinedAt) {
    val actualThingIWant = opt.get
}

これを簡単にする方法はありますか? (不必要に複雑でコードの匂いがします)。理想的には、次のようになります。

if (Some(actualThingIWant) = somethingReturningAnOpt) {
   doSomethingWith(actualThingIWant)
}

そのようなことは可能ですか?

27
laurencer

多分このようなもの:

somethingReturningAnOpt match {
  case Some(actualThingIWant) => doSomethingWith(actualThingIWant)
  case None =>
}

またはpstが示唆するように:

somethingReturningAnOpt.foreach { actualThingIWant =>
  doSomethingWith(actualThingIWant)
}

// or...

for (actualThingIWant <- somethingReturningAnOpt) {
  doSomethingWith(actualThingIWant)
}
33
Rogach

オプションラングリングの 正規ガイド は、Tony Morrisによるものです。

30
Duncan McGregor

または:

somethingReturningAnOpt.map(doSomethingWith(_))

のように:

val str = Some("foo")
str.map(_.toUpperCase)

... flatMapの結果がオプション自体である場合は、doSomethingWithを使用します。

val index = Option(Map("foo" -> "bar"))
index.flatMap(_.get("whatever"))        // Returns None :-)
index.map(_.get("whatever"))            // Returns Some(None) :-(
10

次のコードは、ifの後、actualThingIWantが常に定義されているわけではなく、actualThingIWantを使用しようとしている限り、このコードはコンパイルされないため、何か便利なことはできません。後で。

val opt = somethingReturningAnOpt
if (opt.isDefinedAt) {
    val actualThingIWant = opt.get
}

したがって、デフォルト値を指定する必要があります。これはgetOrElseで実現できます:

val thingIWant = opt.getOrElse(myDefaultValue)

または、actualThingIWantの本文の後にifを付けたくない場合、つまり、オプションが定義されている場合にのみいくつかの副作用をトリガーしたい場合は、次のように記述できます。

opt.foreach{ thingIWant => 
  println(thingIWant)
}

または少し短い

opt.foreach(println)
5
ziggystar