0

私はScalaを持っていOption[T]ます。値がの場合は、値( )をSome(x)返さないプロセスで処理したいのですが、の場合は、エラーを出力したいと思います。UnitNone

次のコードを使用してこれを行うことができますが、より慣用的な方法はOption[T]、をシーケンスとして扱い、、などを使用するmapことであることを理解してforeachいます。これを行うにはどうすればよいですか?

opt match {
  case Some(x) => // process x with no return value, e.g. write x to a file
  case None => // print error message
}
4

5 に答える 5

6

明示的なパターンマッチングは、ユースケースに最も適していると思います。

于 2011-12-16T18:02:09.213 に答える
3

である場合、それ自体が例外opt.getをスローする単純かつ安全に使用することをお勧めします。または、独自の例外をスローする場合は、次のように実行できます。NoSuchElementExceptionoptNone

val x = opt.getOrElse(throw new Exception("Your error message"))
// x is of type T
于 2011-12-16T17:44:40.743 に答える
3

悲しいことに、 ScalaOptionはこれを正確に行う方法を欠いています。私は1つ追加します:

class OptionWrapper[A](o: Option[A]) {
  def fold[Z](default: => Z)(action: A => Z) = o.map(action).getOrElse(default)
}
implicit def option_has_utility[A](o: Option[A]) = new OptionWrapper(o)

これは(私の見解では)少し良い使用法を持っています

op.fold{ println("Empty!") }{ x => doStuffWith(x) }

パターンマッチングの代わりにmap/を使用できることがどのように定義されているかがわかります。getOrElse

または、Eitherすでにfoldメソッドがあります。だからあなたはできる

op.toRight(()).fold{ _ => println("Empty!") }{ x => doStuffWith(x) }

()しかし、これは、左の値(ここでは、つまりUnit)を指定してから、で何をしたいのかを述べるのではなく、その上で関数を定義する必要があることを考えると、少し不器用ですNone

パターンマッチも悪くはありません。特に、コードのブロックが長い場合はそうです。短いものの場合、試合のオーバーヘッドがポイントの邪魔になり始めます。例えば:

op.fold{ printError }{ saveUserInput }

構文上のオーバーヘッドがはるかに少ない

op match {
  case Some(x) => saveUserInput(x)
  case None => printError
}

したがって、一度期待すると、理解しやすくなります。

于 2011-12-16T18:56:00.383 に答える
2

ここでは、パターンマッチングが最良の選択です。

ただし、Optionをシーケンスとして扱い、その上にマップする場合は、Unitが値であるため、それを行うことができます。

opt map { v =>
  println(v) // process v (result type is Unit)
} getOrElse {
  println("error")
}

ちなみに、エラーの出力はある種の「アンチパターン」なので、とにかく例外をスローすることをお勧めします。

opt.getOrElse(throw new SomeException)
于 2011-12-16T18:26:20.950 に答える
2

@missingfaktorが言うように、あなたはパターンマッチングが最も読みやすい結果をもたらす正確なシナリオにいます。Optionに値がある場合は何かをしたい、そうでない場合は何か他のことをしたい。

オプションタイプでマップやその他の関数構造を使用する方法はさまざまですが、一般的に次の場合に役立ちます。

あなたはいくつかのケースを使用し、あなたの場合のようになしのケースを無視したい

opt.map(writeToFile(_)) //(...if None just do nothing)

または、複数のオプションで操作を連鎖させ、すべてがSomeである場合にのみ結果を出したい場合。たとえば、これを行う1つの方法は次のとおりです。

val concatThreeOptions = 
for {
  n1 <- opt1
  n2 <- opt2
  n3 <- opt3
} yield n1 + n2 + n3 // this will be None if any of the three is None
                     // we will either write them all to a file or none of them

しかし、これらのどれもあなたのケースではないようです

于 2011-12-16T18:27:15.680 に答える