8

私のマシンでは、次のコード スニペットのそれぞれが、標準出力 "1" と "2" に出力する代わりにスローと例外をスローします。例外がキャッチされないのはなぜですか?

try {
    [int]$a = 1/0
}
catch {
    write 1
}
finally {
    write 2
}

try {
    [int]$a = 1/0
}
catch [System.Exception] {
    write 1
}
finally {
    write 2
}
4

3 に答える 3

13

定数を使用しているため、インタープリターは結果を事前計算しようとし、ゼロ除算エラーで失敗します。あなたのコードは実行さえされないので、トラップするものは何もありません。

変数を使用するようにコードを変更し、強制的に実行することで、これを自分で確認できます。

try {
    $divisor = 0
    [int]$a = 1/$divisor
}
catch {
    write 1
}
finally {
    write 2
}

Windows PowerShell in Action (p.257)より

この例では、1/$null を使用しています。単純に 1/0 ではなくこれを行う理由は、PowerShell インタープリターが定数式の折りたたみと呼ばれる処理を行うためです。

定数値のみを含む式を調べます。式が見つかると、コンパイル時にその式を 1 回評価するため、実行時に再度実行して時間を無駄にする必要はありません。

これは、ゼロによる除算などの不可能な式がキャッチされ、解析エラーとして扱われることを意味します。構文解析エラーは、対話的に入力されたときにキャッチできず、ログに記録されないため、良い例にはなりません。(あるスクリプトが別のスクリプトを呼び出し、そのスクリプトにこれらのエラーのいずれかがある場合、呼び出し元のスクリプトはそれをキャッチできますが、解析中のスクリプトはそれをキャッチできません。)

于 2012-05-16T12:48:41.660 に答える
4

v2 の RuntimeException はキャッチできません。v3 で修正されました。

ゼロ除算はこのカテゴリに分類されます。

于 2012-05-16T12:56:44.967 に答える
1

その種の行で例外をスローしようとすることができます:trap { "Your Exception" } 1/0
これは例外「0で割る」をスローします。あなたのコードが例外をスローしない理由はよくわかりませんが._.
PS: そうあるべきじゃないのcatch [System.SystemException]?:)

于 2012-05-16T12:39:10.057 に答える