IMO, daha önce C ++ 'da bulunduğundan Java ve C #' ya dahil edildiler. Asıl soru, öyleyse, neden C ++ bu şekilde? C ++ 'nın Tasarım ve Evrimine Göre (§16.3):
tryAnahtar kelime tamamen gereksiz ve böylece olan { }çoklu ifadeleri aslında bir try-blok veya işleyici kullanıldığı durumlar hariç parantez. Örneğin, aşağıdakilere izin vermek önemsiz olurdu:
int f()
{
return g() catch(xxii) { // not C++
error("G() goofed: xxii");
return 22;
};
}
Ancak bunu, destek personelinin karışık kullanıcılardan kurtarması için yedekliliğin getirildiğini açıklamak zor buldum.
Düzenleme: Bunun neden kafa karıştırıcı olacağı konusunda, bence bir problem olacağını anlamak için @Tom Jeffery'nin cevabındaki (ve özellikle de aldığı oyların sayısındaki) yanlış iddialara bakmak gerekiyor. Ayrıştırıcı için, bu eşleştirme gerçekten farklı değil elses ile ifs - diğer bir gruba zorla parantez eksik, tüm catch maddeleri En son ile eşleşir throw. İçerdiği misbegotten dilleri için finallymaddeler aynı şeyi yapar. Ayrıştırıcının bakış açısına göre, bu durumun mevcut durumdan farkına varmaktan yeterince farklı değildir - özellikle gramerler şu anda durduğunda, catchcümleleri bir araya getirmek için gerçekten hiçbir şey yoktur - parantezler, kontroller tarafından kontrol edilen ifadeleri gruplandırır.catch cümlecikler, catch cümleleri kendileri değil.
Ayrıştırıcı yazma bakış açısından, fark neredeyse farkedilmeyecek kadar küçüktür. Eğer böyle bir şeyle başlarsak:
simple_statement: /* won't try to cover all of this */
;
statement: compound_statement
| simple_statement
;
statements:
| statements statement
;
compound_statement: '{' statements '}'
catch_arg: '(' argument ')'
O zaman aradaki fark şu olurdu:
try_clause: 'try' statement
ve:
try_clause: 'try' compound_statement
Aynı şekilde, yakalama cümleleri için:
catch_clause: 'catch' catch_arg statement
vs.
catch_clause: 'catch' catch_arg compound_statement
Tam bir deneme / yakalama bloğunun tanımının değişmesi gerekmez. Her iki şekilde de böyle bir şey olurdu:
catch_clauses:
| catch_clauses catch_clause
;
try_block: try_clause catch_clauses [finally_clause]
;
[Burada [whatever], isteğe bağlı bir şeyi belirtmek için kullanıyorum ve sözdizimi dışında bırakıyorum finally_clauseçünkü bu konuyla ilgili bir etkisi olmadığını düşünüyorum.]
Buradaki tüm Yacc benzeri dilbilgisi tanımını takip etmeyi denemeseniz bile, nokta oldukça kolay bir şekilde özetlenebilir: bu son ifade (başlayarak try_block), catchcümlelerin cümleciklerle eşleştirildiğidir try- ve aynen öyle kalır . Aynı şekilde parantez gerekli olsun veya olmasın.
/ Özetlemek yinelemek için: Birlikte parantez grubu kontrollü ifadeleri ilecatch s, ama yapacak değil grup catchkendilerini bu. Bu nedenle, bu parantezlerin hangisinin hangisiyle gideceğine karar vermede kesinlikle etkisi yoktur . Ayrıştırıcı / derleyici için görev her iki şekilde de aynı derecede kolaydır (veya zor). Buna rağmen, Tom'un cevap (ve Alındıktan yukarı-oy sayısı) @ Aslında böyle bir değişikliğin bol kanıtıdır olur neredeyse kesinlikle şaşırtmak kullanıcıları.catchtry
forparçaları gibi bir ad olmalıdırinitial,conditionvestepsırainitialihtiyacı bir değişken tanımlamak değil vestepbir artım olması gerekmez.