Saya pikir @JackAidley sudah mengatakan intinya , tetapi izinkan saya merumuskannya seperti ini:
tanpa Pengecualian (mis. C)
Dalam aliran kode biasa, Anda memiliki:
if (condition) {
statement;
} else if (less_likely_condition) {
less_likely_statement;
} else {
least_likely_statement;
}
more_statements;
Dalam kasus "kesalahan awal", kode Anda tiba-tiba berbunyi:
/* demonstration example, do NOT code like this */
if (condition) {
statement;
} else {
error_handling;
return;
}
Jika Anda menemukan pola ini - a return
di dalam else
(atau bahkan if
) blok, segera ulang sehingga kode tersebut tidak memiliki else
blok:
/* only code like this at University, to please structured programming professors */
function foo {
if (condition) {
lots_of_statements;
}
return;
}
Di dunia nyata ...
/* code like this instead */
if (!condition) {
error_handling;
return;
}
lots_of_statements;
Ini menghindari bersarang terlalu dalam dan memenuhi kasus "keluar awal" (membantu menjaga pikiran - dan aliran kode - bersih) dan tidak melanggar "memasukkan hal yang lebih mungkin ke dalam if
bagian" karena tidak ada else
bagian .
C
dan pembersihan
Terinspirasi oleh jawaban pada pertanyaan serupa (yang salah), inilah cara Anda melakukan pembersihan dengan C. Anda dapat menggunakan satu atau dua titik keluar di sana, di sini satu untuk dua titik keluar:
struct foo *
alloc_and_init(size_t arg1, int arg2)
{
struct foo *res;
if (!(res = calloc(sizeof(struct foo), 1)))
return (NULL);
if (foo_init1(res, arg1))
goto err;
res.arg1_inited = true;
if (foo_init2(&(res->blah), arg2))
goto err;
foo_init_complete(res);
return (res);
err:
/* safe because we use calloc and false == 0 */
if (res.arg1_inited)
foo_dispose1(res);
free(res);
return (NULL);
}
Anda dapat menutupnya menjadi satu titik keluar jika ada sedikit pembersihan yang harus dilakukan:
char *
NULL_safe_strdup(const char *arg)
{
char *res = NULL;
if (arg == NULL)
goto out;
/* imagine more lines here */
res = strdup(arg);
out:
return (res);
}
Penggunaan goto
ini sangat baik, jika Anda bisa mengatasinya; saran untuk menghindari penggunaan goto
diarahkan pada orang yang belum bisa memutuskan sendiri apakah suatu penggunaan itu baik, dapat diterima, buruk, kode spageti, atau sesuatu yang lain.
Pengecualian
Pembicaraan di atas tentang bahasa tanpa pengecualian, yang saya sendiri lebih suka (saya bisa menggunakan penanganan kesalahan secara eksplisit jauh lebih baik, dan dengan lebih sedikit kejutan). Mengutip igli:
<igli> exceptions: a truly awful implementation of quite a nice idea.
<igli> just about the worst way you could do something like that, afaic.
<igli> it's like anti-design.
<mirabilos> that too… may I quote you on that?
<igli> sure, tho i doubt anyone will listen ;)
Tapi di sini adalah saran bagaimana Anda melakukannya dengan baik dalam bahasa dengan pengecualian, dan kapan Anda ingin menggunakannya dengan baik:
kesalahan kembali saat berhadapan dengan pengecualian
Anda dapat mengganti sebagian besar awal return
dengan melemparkan pengecualian. Namun , aliran program normal Anda , yaitu setiap aliran kode di mana program tidak menemui, baik, pengecualian ... kondisi kesalahan atau semacamnya, tidak akan menimbulkan pengecualian.
Ini berarti bahwa ...
# this page is only available to logged-in users
if not isLoggedIn():
# this is Python 2.5 style; insert your favourite raise/throw here
raise "eh?"
... tidak apa-apa, tapi ...
/* do not code like this! */
try {
openFile(xyz, "rw");
} catch (LockedException e) {
return "file is locked";
}
closeFile(xyz);
return "file is not locked";
… tidak. Pada dasarnya, pengecualian bukanlah elemen aliran kontrol . Ini juga membuat Operasi terlihat aneh bagi Anda ("programmer Java ™ itu selalu memberi tahu kami bahwa pengecualian ini normal") dan dapat menghambat debugging (mis. Beri tahu IDE untuk tidak melakukan pengecualian apa pun). Pengecualian sering membutuhkan lingkungan run-time untuk melepas tumpukan untuk menghasilkan traceback, dll. Mungkin ada lebih banyak alasan untuk tidak melakukannya.
Ini bermuara pada: dalam bahasa yang mendukung pengecualian, gunakan apa pun yang cocok dengan logika dan gaya yang ada dan terasa alami. Jika menulis sesuatu dari awal, dapatkan ini disepakati sejak dini. Jika menulis perpustakaan dari awal, pikirkan konsumen Anda. (Jangan, pernah, gunakan abort()
di perpustakaan juga ...) Tapi apa pun yang Anda lakukan, jangan, sebagai aturan praktis, memiliki pengecualian yang dilemparkan jika operasi berlanjut (kurang lebih) secara normal setelahnya.
saran umum wrt. Pengecualian
Cobalah untuk mendapatkan semua Pengecualian dalam program yang disetujui oleh seluruh tim pengembang terlebih dahulu. Pada dasarnya, rencanakan mereka. Jangan menggunakannya terlalu banyak. Terkadang, bahkan dalam C ++, Java ™, Python, pengembalian kesalahan lebih baik. Terkadang tidak; gunakan dengan pikiran.