Mengapa referensi nol dihindari sementara melemparkan pengecualian dianggap baik-baik saja?

21

Saya tidak begitu mengerti bashing konsisten dari referensi nol oleh beberapa orang bahasa pemrograman. Apa yang buruk dari mereka? Jika saya meminta akses baca ke file yang tidak ada maka saya sangat senang mendapatkan pengecualian atau referensi nol dan namun pengecualian dianggap baik tetapi referensi nol dianggap buruk. Apa alasan di balik ini?

davidk01
sumber
2
Beberapa bahasa mogok di null lebih baik daripada yang lain. Untuk "kode terkelola", seperti .Net / Java, null ref hanyalah jenis masalah lain, sedangkan kode asli lainnya mungkin tidak menangani hal ini dengan anggun (Anda belum menyebut bahasa tertentu). Bahkan di dunia yang dikelola, kadang-kadang Anda ingin menulis kode gagal-aman (disematkan ?, senjata?), Dan kadang-kadang Anda ingin menggerutu dengan keras ASAP (pengujian unit). Kedua jenis kode ini dapat memanggil ke perpustakaan yang sama - itu akan menjadi masalah. Secara umum saya pikir kode yang mencoba untuk tidak menyakiti perasaan komputer adalah ide yang buruk. Keamanan gagal adalah KERAS pula.
Pekerjaan
@ Pekerjaan: Ini menganjurkan kemalasan. Jika Anda tahu cara menangani pengecualian, Anda menanganinya. Kadang-kadang penanganan itu mungkin melibatkan melempar pengecualian lain, tetapi Anda tidak boleh membiarkan pengecualian referensi nol tidak ditangani. Pernah. Itulah mimpi buruk setiap programmer pemeliharaan; itu pengecualian paling tidak berguna di seluruh pohon. Tanyakan saja Stack Overflow .
Aaronaught
atau dengan kata lain - mengapa tidak mengembalikan semacam kode untuk mewakili informasi kesalahan. Argumen ini akan mengamuk selama bertahun-tahun yang akan datang.
gbjbaanb

Jawaban:

24

Referensi Null tidak "dijauhi" lebih dari pengecualian, setidaknya oleh siapa pun yang pernah saya kenal atau baca. Saya pikir Anda salah memahami kebijaksanaan konvensional.

Yang buruk adalah upaya untuk mengakses referensi nol (atau dereferensi pointer nol, dll.). Ini buruk karena selalu menunjukkan bug; Anda tidak akan pernah melakukan sesuatu seperti ini dengan sengaja, dan jika Anda sedang melakukannya dengan sengaja, maka itu bahkan lebih buruk, karena itu membuat mustahil untuk membedakan perilaku yang diharapkan dari perilaku kereta.

Ada beberapa kelompok pinggiran di luar sana yang hanya benar-benar membenci konsep nullity karena suatu alasan, tetapi seperti yang Ed tunjukkan , jika Anda tidak memiliki nullatau nilkemudian Anda hanya perlu menggantinya dengan sesuatu yang lain, yang mungkin mengarah pada sesuatu lebih buruk daripada kerusakan (seperti korupsi data).

Banyak kerangka kerja, pada kenyataannya, merangkul kedua konsep; misalnya, di .NET, pola yang sering Anda lihat adalah sepasang metode, yang diawali dengan kata Try(seperti TryGetValue). Dalam hal Tryini, referensi diatur ke nilai default (biasanya null), dan dalam kasus lain, pengecualian dilemparkan. Tidak ada yang salah dengan kedua pendekatan itu; keduanya sering digunakan di lingkungan yang mendukungnya.

Itu benar-benar semua tergantung pada semantik. Jika nullnilai pengembalian yang valid, seperti dalam kasus umum mencari koleksi, maka kembali null. Di sisi lain, jika itu bukan nilai balik yang valid - misalnya, mencari catatan menggunakan kunci utama yang berasal dari database Anda sendiri - maka kembali nullakan menjadi ide yang buruk karena penelepon tidak akan mengharapkannya dan mungkin tidak akan memeriksanya.

Ini benar-benar sangat sederhana untuk mengetahui semantik mana yang digunakan: Apakah masuk akal untuk hasil suatu fungsi yang tidak terdefinisi? Jika demikian, Anda dapat mengembalikan referensi nol. Jika tidak, berikan pengecualian.

Aaronaught
sumber
5
Sebenarnya ada bahasa yang tidak memiliki nol atau nol dan tidak "perlu menggantinya dengan yang lain". Referensi yang dapat dihapus menyiratkan bahwa mungkin ada sesuatu di sana, atau mungkin tidak ada. Jika Anda hanya mengharuskan pengguna untuk secara eksplisit memeriksa apakah ada sesuatu di sana, Anda telah menyelesaikan masalah. Lihat haskell untuk contoh kehidupan nyata.
Johanna Larsson
3
@ErikKronberg, ya, "kesalahan miliaran dolar" dan semua omong kosong itu, parade orang-orang yang merencanakan ini dan mengklaimnya sebagai yang baru dan menarik tidak pernah berakhir, itu sebabnya utas komentar sebelumnya dihapus. Pengganti revolusioner yang tidak pernah gagal dibicarakan orang ini selalu merupakan varian dari Null Object, Option atau Contract, yang tidak secara ajaib menghilangkan kesalahan logika yang mendasarinya, mereka hanya menunda atau mempromosikannya, masing-masing. Bagaimanapun, ini adalah jelas pertanyaan tentang bahasa pemrograman yang melakukan memiliki null, sehingga benar-benar, Haskell cukup relevan di sini.
Aaronaught
1
apakah Anda serius berpendapat bahwa tidak memerlukan tes untuk null sama baiknya dengan meminta itu?
Johanna Larsson
3
@ErikKronberg: Ya, saya "serius berargumen" bahwa harus menguji nol tidak terlalu berbeda dari (a) harus merancang setiap tingkatan aplikasi di sekitar perilaku Obyek Null, (b) harus mencocokkan pola Opsi sepanjang waktu, atau (c) tidak memungkinkan callee untuk mengatakan "Saya tidak tahu" dan memaksakan pengecualian atau crash. Ada alasan mengapa nullbertahan begitu lama, dan sebagian besar orang yang mengatakan sebaliknya tampaknya adalah akademisi dengan sedikit pengalaman merancang aplikasi dunia nyata dengan kendala seperti persyaratan yang tidak lengkap atau konsistensi akhirnya.
Aaronaught
3
@Aaronaught: Terkadang saya berharap ada tombol downvote untuk komentar. Tidak ada alasan untuk berteriak seperti itu.
Michael Shaw
11

Perbedaan besar adalah bahwa jika Anda meninggalkan kode untuk menangani NULLs, kode Anda akan terus menerjang pada tahap selanjutnya dengan beberapa pesan kesalahan yang tidak terkait, di mana seperti halnya pengecualian, pengecualian akan dimunculkan pada titik awal kegagalan (pembukaan file untuk dibaca dalam contoh Anda).

John Gaines Jr.
sumber
4
Kegagalan untuk menangani NULL adalah ketidaktahuan yang disengaja dari antarmuka antara kode Anda dan apa pun yang mengembalikannya. Pengembang yang akan membuat kesalahan itu akan membuat orang lain dalam bahasa yang tidak melakukan NULL.
Blrfl
@ Blrfl, metode idealnya cukup pendek, dan dengan demikian mudah untuk mengetahui dengan tepat di mana masalahnya terjadi. Seorang debugger yang baik biasanya bisa berburu pengecualian referensi nol dengan baik, meskipun kodenya panjang. Apa yang harus saya lakukan jika saya mencoba membaca pengaturan kritis dari registri, yang tidak ada di sana? Registri saya kacau dan saya lebih baik gagal dan menjengkelkan pengguna, daripada diam-diam menciptakan kembali sebuah node dan mengaturnya ke default. Bagaimana jika virus melakukan ini? Jadi, jika saya mendapatkan nol, haruskah saya melempar pengecualian khusus atau membiarkannya robek? Dengan metode pendek apa bedanya?
Pekerjaan
@ Pekerjaan: Bagaimana jika Anda tidak memiliki debugger? Anda menyadari bahwa 99,99% dari waktu aplikasi Anda akan berjalan di lingkungan rilis? Ketika itu terjadi, Anda akan berharap bahwa Anda telah menggunakan pengecualian yang lebih bermakna. Aplikasi Anda mungkin masih harus gagal dan mengganggu pengguna, tetapi setidaknya itu akan menampilkan informasi debug yang akan memungkinkan Anda untuk segera melacak masalah, sehingga menjaga gangguan tersebut seminimal mungkin.
Aaronaught
@ Blfl, kadang-kadang saya tidak ingin menangani kasus di mana null akan alami untuk kembali. Sebagai contoh, misalkan saya memiliki kunci pemetaan kontainer untuk nilai-nilai. Jika logika saya menjamin bahwa saya tidak pernah mencoba membaca nilai-nilai yang tidak saya simpan pertama kali, maka saya seharusnya tidak pernah mendapatkan null kembali. Dalam hal ini, saya lebih suka memiliki pengecualian yang menyediakan informasi sebanyak mungkin untuk menunjukkan apa yang salah, daripada mengembalikan nol untuk gagal secara misterius di tempat lain dalam program.
Winston Ewert
Dengan kata lain, dengan pengecualian saya harus secara eksplisit menangani kasus yang tidak biasa ini atau program saya langsung mati. Dengan referensi nol jika kode tidak secara eksplisit menangani kasus yang tidak biasa, ia akan mencoba untuk pincang. Saya pikir lebih baik untuk mengambil kasus gagal sekarang.
Winston Ewert
8

Karena nilai nol bukan bagian penting dari bahasa pemrograman dan merupakan sumber bug yang konsisten. Seperti yang Anda katakan, membuka file dapat menyebabkan kegagalan, yang dapat dikomunikasikan kembali sebagai nilai pengembalian nol atau melalui pengecualian. Jika nilai nol tidak diizinkan maka ada cara konsisten dan tunggal untuk mengkomunikasikan kegagalan.

Juga, ini bukan masalah yang paling umum dengan nulls. Kebanyakan orang ingat untuk memeriksa nol setelah memanggil fungsi yang dapat mengembalikannya. Masalah muncul jauh lebih banyak dalam desain Anda sendiri dengan memungkinkan variabel menjadi nol pada berbagai titik dalam pelaksanaan program Anda. Anda dapat mendesain kode Anda sehingga nilai-nilai nol tidak pernah diizinkan, tetapi jika nol tidak diizinkan di tingkat bahasa, semua ini tidak diperlukan.

Namun, dalam praktiknya Anda masih perlu beberapa cara untuk menandakan jika suatu variabel diinisialisasi atau tidak. Anda kemudian akan memiliki bentuk bug di mana program Anda tidak crash, tetapi terus menggunakan beberapa nilai default yang mungkin tidak valid. Sejujurnya saya tidak tahu mana yang lebih baik. Untuk uang saya, saya suka crash awal dan sering.

Ed S.
sumber
Pertimbangkan subclass yang tidak diinisialisasi dengan string pengenal, dan semua metodenya melempar pengecualian. Jika salah satu dari ini muncul, Anda tahu apa yang terjadi. Pada sistem tertanam dengan memori terbatas, versi produksi dari pabrik Uninitialized hanya dapat mengembalikan nol.
Jim Balter
3
@ Jim Balter: Saya kira saya bingung bagaimana itu akan sangat membantu dalam prakteknya. Dalam program non-sepele apa pun Anda harus berurusan dengan nilai yang mungkin tidak diinisialisasi. Jadi, harus ada beberapa cara untuk menandakan nilai default. Karena itu, Anda masih harus memeriksa ini sebelum melanjutkan. Jadi, alih-alih potensi kerusakan, Anda sekarang berpotensi bekerja dengan data tidak valid.
Ed S.
1
Anda juga tahu apa yang terjadi ketika Anda mendapatkan nullsebagai nilai pengembalian: Informasi yang Anda minta tidak ada. Tidak ada perbedaan. Either way, penelepon harus memvalidasi nilai kembali jika itu benar-benar perlu menggunakan informasi itu untuk tujuan tertentu. Apakah itu memvalidasi null, objek nol, atau monad tidak membuat perbedaan praktis.
Aaronaught
1
@ Jim Balter: Benar, saya masih tidak melihat perbedaan praktis, dan saya tidak melihat bagaimana hal itu membuat hidup lebih mudah bagi orang yang menulis program nyata di luar akademisi. Bukan berarti tidak ada manfaatnya, hanya saja itu tidak tampak bagi saya.
Ed S.
1
Saya telah menjelaskan perbedaan praktis dengan kelas yang tidak diinisialisasi dua kali - ini mengidentifikasi asal item nol - memungkinkan untuk menentukan bug ketika terjadi null pada null. Adapun bahasa yang dirancang di sekitar paradigma nol-kurang, mereka menghindari masalah sejak awal - mereka menyediakan cara alternatif untuk memprogram. Itu menghindari variabel yang tidak diinisialisasi; yang mungkin terasa sulit untuk dipahami jika Anda tidak terbiasa dengan mereka. Pemrograman terstruktur, yang juga menghindari sejumlah besar bug, juga pernah dianggap "akademis".
Jim Balter
5

Tony Hoare, yang menciptakan ide referensi nol di tempat pertama, menyebutnya kesalahan satu juta dolar .

Masalahnya bukan tentang referensi nol per-se, tetapi tentang kurangnya pengecekan jenis yang tepat di sebagian besar (kecuali) jenis bahasa aman.

Kurangnya dukungan ini, dari bahasa, berarti bahwa bug "null-bug" mungkin bersembunyi di program untuk waktu yang lama sebelum terdeteksi. Seperti itulah sifat bug, tentu saja, tetapi "null-bug" sekarang diketahui dapat dihindari.

Masalah ini terutama hadir dalam C atau C ++ (misalnya) karena kesalahan "keras" yang disebabkannya (crash program, langsung, tanpa pemulihan yang elegan).

Dalam bahasa lain, selalu ada pertanyaan tentang bagaimana menanganinya.

Di Java atau C # Anda akan mendapatkan pengecualian jika Anda mencoba untuk memanggil metode pada referensi nol, dan mungkin tidak apa-apa. Dan oleh karena itu sebagian besar programmer Java atau C # terbiasa dengan ini dan tidak mengerti mengapa orang ingin melakukan sebaliknya (dan menertawakan C ++).

Di Haskell, Anda harus secara eksplisit memberikan tindakan untuk case nol, dan karena itu programmer Haskell menertawakan rekan-rekan mereka, karena mereka sudah benar (benar?).

Ini benar-benar debat kode kesalahan / pengecualian lama, tapi kali ini dengan Nilai Sentinel sebagai pengganti kode kesalahan.

Seperti biasa, mana yang paling tepat sangat tergantung pada situasi dan semantik yang Anda cari.

Matthieu M.
sumber
Tepat. nullbenar-benar jahat, karena merongrong sistem tipe . (Memang, alternatifnya memiliki kelemahan dalam verbositasnya, setidaknya dalam beberapa bahasa.)
Mekanik keong
2

Anda tidak bisa melampirkan pesan kesalahan yang bisa dibaca manusia ke pointer nol.

(Namun, Anda dapat meninggalkan pesan kesalahan dalam file log.)

Dalam beberapa bahasa / lingkungan yang memungkinkan aritmatika pointer, jika salah satu argumen pointer adalah nol dan diizinkan ke dalam perhitungan, hasilnya akan menjadi pointer yang tidak valid dan tidak nol . (*) Lebih banyak kekuatan untuk Anda.

(*) Hal ini sering terjadi pada pemrograman COM , di mana jika Anda mencoba memanggil ke metode antarmuka tetapi pointer antarmuka adalah nol, itu akan menghasilkan panggilan ke alamat yang tidak valid yang hampir, tetapi tidak cukup, persis tidak seperti nol.

rwong
sumber
2

Mengembalikan NULL (atau angka nol, atau boolean false) untuk memberi sinyal kesalahan adalah salah secara teknis dan konseptual.

Secara teknis, Anda membebani pemrogram dengan memeriksa nilai kembali segera , pada titik yang tepat di mana ia dikembalikan. Jika Anda membuka dua puluh file berturut-turut, dan pensinyalan kesalahan dilakukan dengan mengembalikan NULL, maka kode yang dikonsumsi harus memeriksa setiap file yang dibaca secara individual, dan keluar dari setiap loop dan konstruksi yang serupa. Ini adalah resep yang sempurna untuk kode yang berantakan. Namun, jika Anda memilih untuk memberi sinyal kesalahan dengan melemparkan pengecualian, kode yang dikonsumsi dapat memilih untuk menangani pengecualian dengan segera, atau membiarkannya naik ke level sebanyak yang sesuai, bahkan di seluruh panggilan fungsi. Ini membuat kode lebih bersih.

Secara konseptual, jika Anda membuka file dan ada yang tidak beres, maka mengembalikan nilai (bahkan NULL) salah. Anda tidak memiliki apa pun untuk dikembalikan, karena operasi Anda tidak selesai. Mengembalikan NULL adalah padanan konseptual dari "Saya telah berhasil membaca file, dan inilah yang dikandungnya - tidak ada". Jika itu yang ingin Anda ungkapkan (yaitu, jika NULL masuk akal sebagai hasil aktual untuk operasi yang dimaksud), maka tentu saja kembalikan NULL, tetapi jika Anda ingin memberi sinyal kesalahan, gunakan pengecualian.

Secara historis, kesalahan dilaporkan dengan cara ini karena bahasa pemrograman seperti C tidak memiliki penanganan perkecualian yang dibangun ke dalam bahasa tersebut, dan cara yang disarankan (menggunakan lompat jauh) agak berbulu dan agak kontra-intuitif.

Ada juga sisi pemeliharaan untuk masalah ini: dengan pengecualian, Anda harus menulis kode tambahan untuk menangani kegagalan; jika tidak, program akan gagal lebih awal dan sulit (mana yang baik). Jika Anda mengembalikan NULL ke sinyal kesalahan, perilaku default untuk program ini adalah mengabaikan kesalahan dan melanjutkannya, sampai mengarah ke masalah lain di jalan - data rusak, segfaults, NullReferenceExceptions, tergantung pada bahasanya. Untuk memberi sinyal kesalahan awal dan keras, Anda harus menulis kode tambahan, dan coba tebak: itulah bagian yang ditinggalkan ketika Anda berada di tenggat waktu yang ketat.

tammmer
sumber
1

Seperti yang telah ditunjukkan, banyak bahasa tidak mengonversi dereferensi penunjuk nol menjadi pengecualian yang dapat ditangkap. Melakukan itu adalah trik yang relatif modern. Ketika masalah null pointer pertama kali dikenali, pengecualian bahkan belum ditemukan.

Jika Anda mengizinkan null pointer sebagai kasus yang valid, itu adalah kasus khusus. Anda memerlukan logika penanganan kasus khusus, seringkali di banyak tempat berbeda. Itu kompleksitas ekstra.

Apakah itu terkait dengan pointer berpotensi nol atau tidak, jika Anda tidak menggunakan lemparan pengecualian untuk menangani kasus luar biasa, Anda harus menangani kasus luar biasa dengan cara lain. Biasanya, setiap panggilan fungsi harus diperiksa untuk kasus-kasus yang luar biasa, baik untuk mencegah panggilan fungsi tidak tepat, atau untuk mendeteksi kasus kegagalan ketika fungsi keluar. Itu kompleksitas ekstra yang bisa dihindari menggunakan pengecualian.

Semakin banyak kompleksitas biasanya berarti lebih banyak kesalahan.

Alternatif untuk menggunakan pointer nol dalam struktur data (misalnya untuk menandai awal / akhir daftar tertaut) termasuk menggunakan item sentinel. Ini dapat memberikan fungsionalitas yang sama dengan kompleksitas yang jauh lebih sedikit. Namun, ada cara lain untuk mengelola kompleksitas. Salah satu caranya adalah dengan membungkus pointer berpotensi nol dalam kelas pointer pintar sehingga pemeriksaan nol hanya diperlukan di satu tempat.

Apa yang harus dilakukan tentang pointer nol ketika terdeteksi? Jika Anda tidak dapat membangun dalam penanganan kasus luar biasa, Anda selalu dapat melemparkan pengecualian, dan secara efektif mendelegasikan penanganan kasus khusus ke penelepon. Dan itulah yang dilakukan beberapa bahasa secara default ketika Anda melakukan dereferensi pointer nol.

Steve314
sumber
1

Khusus untuk C ++, tetapi ada referensi nol dijauhi di sana karena nol semantik di C ++ dikaitkan dengan jenis pointer. Cukup masuk akal jika fungsi buka file gagal dan mengembalikan pointer nol; sebenarnya fopen()fungsi melakukan hal itu.

MSalters
sumber
Memang, jika Anda menemukan diri Anda dengan referensi nol di C ++, itu karena program Anda sudah rusak .
Kaz Dragon
1

Itu tergantung pada bahasanya.

Misalnya, Objective-C memungkinkan Anda untuk mengirim pesan ke objek nol (nil) tanpa masalah. Panggilan ke nil mengembalikan nihil dan dianggap sebagai fitur bahasa.

Saya pribadi suka karena Anda dapat mengandalkan perilaku itu dan menghindari semua if(obj == null)konstruksi bersarang yang berbelit-belit .

Contohnya:

if (myObject != nil && [myObject doSomething])
{
    ...
}

Dapat disingkat menjadi:

if ([myObject doSomething])
{
    ...
}

Singkatnya, itu membuat kode Anda lebih mudah dibaca.

Martin Wickman
sumber
0

Saya tidak memberikan teriakan apakah Anda mengembalikan nol atau melemparkan pengecualian, selama Anda mendokumentasikannya.

SnoopDougieDoug
sumber
Dan juga beri nama : GetAddressMaybeatau GetSpouseNameOrNull.
rwong
-1

Referensi Null biasanya terjadi karena sesuatu dalam logika program tidak terjawab, yaitu: Anda mendapatkan baris kode tanpa melalui pengaturan yang diperlukan untuk blok kode itu.

Di sisi lain, jika Anda melemparkan pengecualian untuk sesuatu itu berarti Anda mengenali bahwa situasi tertentu dapat terjadi dalam operasi normal program, dan sedang ditangani.

Dave
sumber
2
Referensi nol dapat "terjadi" karena sejumlah besar alasan, sangat sedikit dari mereka yang berkaitan dengan apa pun yang terlewatkan. Mungkin Anda juga bingung dengan pengecualian referensi nol .
Aaronaught
-1

Referensi kosong sering sangat berguna: Misalnya, elemen dalam daftar tertaut dapat memiliki beberapa penerus atau tidak ada penerus. Menggunakan nulluntuk "tidak ada penerus" adalah hal yang wajar. Atau, seseorang dapat memiliki pasangan atau tidak - menggunakan nulluntuk "seseorang tidak memiliki pasangan" adalah sangat alami, jauh lebih alami daripada memiliki beberapa "tidak memiliki pasangan" - nilai khusus yang Person.Spousedapat dirujuk oleh anggota tersebut.

Tetapi: Banyak nilai tidak opsional. Dalam program OOP yang khas, saya akan mengatakan lebih dari setengah referensi tidak dapat nullsetelah inisialisasi, atau program akan gagal. Kalau tidak, kodenya harus penuh dengan if (x != null)cek. Jadi mengapa setiap referensi harus dibatalkan secara default? Itu harus benar-benar sebaliknya: variabel harus non-nullable secara default, dan Anda harus secara eksplisit mengatakan "oh, dan nilai ini juga bisa null".

nikie
sumber
adakah sesuatu dari diskusi ini yang ingin Anda tambahkan kembali ke jawaban Anda? Utas komentar ini mulai sedikit panas, dan kami ingin membereskannya. Setiap diskusi panjang harus dilakukan untuk mengobrol .
Di tengah semua pertengkaran itu mungkin ada satu atau dua poin yang menarik. Sayangnya saya tidak melihat komentar Markus sampai saya memangkas kembali diskusi panjang. Di masa mendatang harap tandai jawaban Anda untuk perhatian moderator jika Anda ingin menyimpan komentar sampai Anda punya waktu untuk meninjaunya dan mengedit jawaban Anda dengan tepat.
Josh K
-1

Pertanyaan Anda membingungkan. Maksud Anda pengecualian referensi nol (yang sebenarnya disebabkan oleh upaya untuk dereferensi nol)? Alasan yang jelas untuk tidak menginginkan jenis pengecualian itu adalah bahwa ia tidak memberi Anda informasi tentang apa yang salah, atau bahkan kapan - nilainya bisa disetel ke nol pada titik mana pun dalam program. Anda menulis "Jika saya meminta akses baca ke file yang tidak ada maka saya sangat senang mendapatkan pengecualian atau referensi nol" - tetapi Anda tidak harus benar-benar bahagia mendapatkan sesuatu yang tidak memberikan indikasi penyebabnya . Tidak ada dalam string "upaya dilakukan untuk dereference null" apakah ada disebutkan membaca atau file yang tidak ada. Mungkin maksud Anda bahwa Anda akan sangat senang mendapatkan null sebagai nilai balik dari panggilan baca - itu masalah yang sangat berbeda, tetapi masih memberi Anda informasi tentang mengapa pembacaan gagal; saya t'

Jim Balter
sumber
Tidak, maksud saya bukan pengecualian referensi nol. Dalam semua bahasa saya tahu variabel tidak diinisialisasi tetapi dideklarasikan adalah beberapa bentuk nol.
davidk01
Tetapi pertanyaan Anda bukan tentang variabel yang tidak diinisialisasi. Dan ada bahasa yang tidak menggunakan null untuk variabel yang tidak diinisialisasi, melainkan menggunakan objek wrapper yang secara opsional dapat berisi nilai - Scala dan Haskell, misalnya.
Jim Balter
1
"... tetapi sebaliknya menggunakan objek pembungkus yang secara opsional dapat mengandung nilai ." Yang jelas tidak seperti tipe nullable .
Aaronaught
1
Dalam haskell tidak ada yang namanya variabel tidak diinisialisasi. Anda berpotensi mendeklarasikan IORef dan menaburinya dengan None sebagai nilai awal, tetapi itu cukup analog dengan mendeklarasikan variabel dalam beberapa bahasa lain dan membiarkannya tidak diinisialisasi yang membawa semua masalah yang sama dengannya. Bekerja di inti murni fungsional di luar IO monad haskell programmer tidak memiliki jalan lain untuk jenis referensi sehingga tidak ada masalah referensi nol.
davidk01
1
Jika Anda memiliki nilai "Hilang" yang luar biasa, itu persis sama dengan nilai "nol" luar biasa - jika Anda memiliki alat yang sama tersedia untuk menanganinya. Itu "jika" yang signifikan. Anda perlu kompleksitas ekstra untuk menangani kasing itu. Di Haskell, pencocokan pola dan sistem tipe menyediakan cara untuk membantu mengelola kerumitan itu. Namun, ada alat lain untuk mengelola kompleksitas dalam bahasa lain. Pengecualian adalah salah satu alat tersebut.
Steve314