IMO、これらは主にC ++にすでに存在するため、JavaおよびC#に含まれています。本当の問題は、C ++がなぜそうなのかということです。よるCの設計と進化++(§16.3):
このtry
キーワードは完全に冗長であるため{ }
、複数のステートメントがtryブロックまたはハンドラーで実際に使用される場合を除き、括弧も完全に冗長です。たとえば、以下を許可するのは簡単なことです。
int f()
{
return g() catch(xxii) { // not C++
error("G() goofed: xxii");
return 22;
};
}
しかし、サポート担当者を混乱したユーザーから守るために冗長性が導入されたことを説明するのは非常に難しいと感じました。
編集:なぜこれが混乱するかについては、問題があることを認識するために、@ Tom Jefferyの答え(および特に、それが受け取ったアップ投票の数)の誤った主張を見るだけでよいと思います。パーサーにとって、これはelse
sとif
sのマッチングと実際には違いはありません。他のグループ化を強制する中括弧がなく、すべての catch
句が最新のに一致しthrow
ます。それを含む誤って誤解された言語については、finally
条項も同じことをします。パーサーの観点から見ると、これは現在の状況と気づくのに十分な違いはありません-特に、現在の文法では、catch
句をグループ化することは本当にありません-括弧は、catch
catch句ではなく句。
パーサーを書くという観点から見ると、その差はほとんど気付かないほどです。このようなものから始める場合:
simple_statement: /* won't try to cover all of this */
;
statement: compound_statement
| simple_statement
;
statements:
| statements statement
;
compound_statement: '{' statements '}'
catch_arg: '(' argument ')'
次に、違いは次のようになります。
try_clause: 'try' statement
そして:
try_clause: 'try' compound_statement
同様に、catch句の場合:
catch_clause: 'catch' catch_arg statement
対
catch_clause: 'catch' catch_arg compound_statement
ただし、完全なtry / catchブロックの定義を変更する必要はまったくありません。いずれにしても、それは次のようなものになります。
catch_clauses:
| catch_clauses catch_clause
;
try_block: try_clause catch_clauses [finally_clause]
;
[ここでは[whatever]
、オプションの何かを示すために使用していますが、aの構文は省略しています。finally_clause
なぜなら、それが問題に関係しているとは思わないからです。]
そこにあるYaccのような文法の定義すべてに従おうとしない場合でも、ポイントはかなり簡単に要約できます:最後のステートメント(で始まるtry_block
)は、catch
句が句と一致するものでtry
あり、正確にそのままです中かっこが必要かどうかに関係なく同じです。
繰り返し/要約する:中括弧は、s によって制御されるステートメントをグループ化しますcatch
が、s自体はグループ化しませんcatch
。そのため、これらの中括弧は、どちらがどちらを使用するかを決定する際にまったく効果がありません。パーサー/コンパイラの場合、タスクはどちらの方法でも同様に簡単(または難しい)です。それにも関わらず、@ Tomの回答(および受け取った賛成票の数)は、そのような変更がユーザーを混乱させることはほぼ確実であるという事実の十分な実証を提供します。catch
try
for
部品は次のように命名されなければならないinitial
、condition
とstep
としてinitial
必要変数を定義しないと、step
増分である必要はありません。