9

JavaからScalaへのスイッチャーとして、私は日常的にnull処理のようなものを書き直していることに気づきます。

val itemOpt: Option[Item] = items.get(coords) // "items" is something like a Map
if (itemOpt.isDefined) {
  val item = itemOpt.get
  // do something with item, querying item fields a lot of times, for example
  if (item.qty > 10) {
    storeInVault(item.name, item.qty, coords)
  } else {
    storeInRoom(item)
  }
}

見た目は醜く、Javaから書き直されたコードのように見えます。

Item item = items.get(coords);
if (item != null) {
  // do something with item, querying item fields a lot of times, for example
}

Javaでも見苦しいですが、少なくとも1行少なくなっています。Scalaでこのような単純なケースを処理するためのベストプラクティスは何ですか?私はすでにのコレクションを知ってflatMapおり、処理することを知っています。また、デフォルト値を処理することも知っています。私は次のようなことを夢見ています:flattenOption[Stuff]getOrElse

items.get(coords).doIfDefined(item =>
  // do stuff with item
)

Optionしかし、 APIにはそのようなものは見当たりません。

4

4 に答える 4

12

非常に人気のある使用パターン:

val item: Option[Int] = None
val result = item map (_ + 1) getOrElse 0

mapしたがって、値が定義されている場合は、値を変換するために使用するだけです。

内に格納されている値を使用するだけの場合はOption、次を使用しますforeach

item foreach { it =>
    println(it)
}

ご覧のとおり、Option多くの収集メソッドもサポートしているため、実際には新しいAPIを学ぶ必要はありません。1つまたは0つの要素を持つコレクションとして扱うことができます。

于 2012-12-18T20:59:13.263 に答える
7

これはあなたがやろうとしていることを達成するはずです:

items.get(coords).foreach{ item => 
  //do stuff
}
于 2012-12-18T20:56:35.523 に答える
5

このトニーモリスの投稿を確認してください。オプションを理解しようとしたとき、とても助かりました。コードは次のように書き直すことができます。

for (item <- items.get(coords)) { // "items" is something like a Map
  // do something with item, querying item fields a lot of times, for example
  if (item.qty > 10) {
    storeInVault(item.name, item.qty, coords)
  } else {
    storeInRoom(item)
  }
}
于 2012-12-19T00:06:30.567 に答える
3

ifまた、オプションはガード付きのパターンマッチングで使用できます。個人的にはこのシナリオで使うのが好きで、読みやすいと思います。

mapオプションは、オプションがない場合にのみ効果があるためNone、最初にそれを実行してから、パターンマッチングを使用して、itemOptがまたはであるSomeかどうかを確認できますNone

def shouldInVault(item: Item) = item.qty > 10

val itemOpt: Option[Item] = items.get(coords).map(...)

itemOpt match {
    case Some(item) if shouldInVault(item) => storeInVault(item.name, item.qty, coords)
    case Some(item) => storeInRoom(item)
    case None =>
}
于 2012-12-19T01:00:27.713 に答える