15

Scalaから始めて、Either私が知っているもの(この場合はJavaから)と新しい概念を自然に比較することについて読んでいます。チェックされた例外の概念との違いはありEitherますか?

両方の場合において

  • 失敗の可能性は、メソッドで明示的に注釈が付けられます(throwsまたは戻りEitherます)
  • プログラマーは、エラーケースが発生したときに直接処理するか、上に移動することができます(再びEither
  • エラーの理由を発信者に通知する方法があります

Eitherチェックされた例外と同様のエラーがないため、コードを記述するためにfor-comprehensionsを使用すると思います。

違いがわからない初心者は私だけなのかしら。

ありがとう

4

3 に答える 3

13

Either単なる例外以外にも使用できます。たとえば、ユーザーにinputと入力するか、その入力を含むファイルを指定する場合は、それをとして表すことができますEither[String, File]

Either例外処理によく使用されます。チェックされた例外とチェックされた例外の主な違いEitherは、の制御フローEitherが常に明示的であるということです。Eitherコンパイラーは、あなたが;を扱っていることを本当に忘れさせません。Either気づかないうちに複数の場所からsを収集することはなく、返されるものはすべてEither、などである必要があります。このため、Either何か異常が発生した場合ではなく、制御プログラムの通常の部分として使用します。実行。また、Eitherスタックトレースをキャプチャしないため、通常の例外よりもはるかに効率的です。

もう1つの違いは、制御フローに例外を使用できることです。3つのネストされたループからジャンプする必要がありますか?問題ありません-例外を(スタックトレースなしで)スローし、外側でキャッチします。5つのネストされたメソッド呼び出しからジャンプする必要がありますか?問題ない!どちらもこのようなものを供給しません。

とはいえ、ご指摘のとおり、多くの類似点があります。情報を返すことができます(ただしEither、それは些細なことですが、チェックされた例外を使用すると、必要な追加情報を格納するための独自のクラスを作成できます)。渡すEitherことも、他の何かに折りたたむこともできます。

Eitherしたがって、要約すると、明示的なエラー処理に関して例外をチェックして同じことを実行できますが、実際には比較的異なります。特に、Eitherさまざまな状態の作成と受け渡しが非常に簡単になりますが、チェックされた例外は、通常の制御フローをすべてバイパスして、異常な状態に適切に対処できる場所に戻るのに適しています。

于 2012-05-30T14:54:35.017 に答える
2

はい、Either言語に例外を埋め込む方法です。失敗する可能性のある一連の操作により、ローカル以外のサイトにエラー値がスローされる可能性があります。

Rexが言及した実際的な問題に加えて、Either:の単純なセマンティクスから得られるいくつかの追加事項があります。

  • Eitherモナドを形成します。したがって、に評価される式のセットに対してモナディック演算を使用できますEither。たとえば、結果をテストせずに短絡評価を行う場合
  • Eitherは型内にあるため、値の誤った処理を追跡するには、型チェッカーだけで十分です。

エラーメッセージ(Left s)または成功した値のいずれかを返すことができるようになったら、Haskellで行われているように、エラーハンドラーに加えてRight v、例外を最上位に重ねることができます。EitherMonadError

于 2012-05-30T16:28:46.633 に答える
2

どちらも、排他的論理和を形成する戻り署名に関して、チェックされた例外と同等です。結果は、スローされた例外XまたはAになる可能性があります。ただし、例外をスローすることは、例外を返すことと同じではありません。最初の例外は、参照透過性ではありません。

ScalaのEitherが(2.9の時点で)同等ではない場合、returnタイプは正にバイアスされており、例外を抽出/分解するための努力が必要です。Eitherはバイアスされていません。左または右の値を明示的に要求する必要があります。これはいくつかの議論のトピックであり、実際には少し苦痛です–どちらかの生成メソッドへの次の3つの呼び出しを検討してください

for {
  a <- eitherA("input").right
  b <- eitherB(a).right
  c <- eitherC(b).right
} yield c // Either[Exception, C]

RHSを手動でスレッド化する必要があります。これはそれほど面倒ではないように思われるかもしれませんが、実際には苦痛であり、新参者にとってはいくぶん驚くべきことです。

于 2012-05-31T02:38:15.493 に答える