カスタム例外タイプはcase class
es にする必要がありますか?
プラス面として、抽出器があります。
マイナス面としては、等価セマンティクスが正しくありません。しかし、オーバーライドすることでそれを回避できますequals
。
case class
では、概念レベルでそれらをesにすることは理にかなっていますか?
カスタム例外タイプはcase class
es にする必要がありますか?
プラス面として、抽出器があります。
マイナス面としては、等価セマンティクスが正しくありません。しかし、オーバーライドすることでそれを回避できますequals
。
case class
では、概念レベルでそれらをesにすることは理にかなっていますか?
もちろん、これは非常に主観的なものですが、私の意見では、例外クラスをケース クラスとして使用することをお勧めします。主な理論的根拠は、例外をキャッチするときにパターン マッチングを行っていることであり、ケース クラスはパターン マッチングで使用する方がはるかに優れています。ケース クラスの例外を使用する場合に、catch ブロックでパターン マッチングの全機能を使用する機能を利用する例を次に示します。
object IOErrorType extends Enumeration {
val FileNotFound, DeviceError, LockedFile = Value
}
case class IOError(message: String, errorType: IOErrorType.Value) extends Exception(message)
def doSomeIO() { throw IOError("Oops, file not found!", IOErrorType.FileNotFound) }
try {
doSomeIO()
} catch {
case IOError( msg, IOErrorType.FileNotFound ) =>
println("File not found, please check the path! (" + msg + ")")
}
この例では、例外は 1 つしかありerrorType
ませんが、発生した正確なエラーの種類を知りたい場合のフィールドが含まれています (通常、これは例外の階層によってモデル化されます。これが良いとか悪いと言っているわけではありません。例は単なる説明です)。IOError
これはケース クラスであるため、単純case IOError( msg, IOErrorType.FileNotFound )
にエラー タイプ の例外をキャッチすることができますIOErrorType.FileNotFound
。ケース クラスで無料で取得できるエクストラクタがなければ、毎回例外をキャッチし、実際に興味がない場合に備えて再スローする必要があり、これは間違いなく冗長です。
あなたは、ケース クラスが間違った等価セマンティクスを与えると言っています。私はそうは思わない。あなたは、例外クラスの作成者として、どの等価セマンティクスが意味を持つかを決定します。結局のところ、例外をキャッチする場合、catch ブロックは、通常はタイプのみに基づいてキャッチする例外を決定する場所ですが、私の例のように、フィールドの値などに基づいて決定することもできます。ポイントは、例外クラスの等価セマンティクスはそれとはほとんど関係がないということです。
例外ケース クラスを作成することで失われる一般的なイディオムの 1 つは、エラー状態の特異性を高めるために使用されるサブクラス化を使用して、例外のサブクラス階層を作成するパターンです。ケース クラスはサブクラス化できません。