Menggunakan null dengan benar
Ada berbagai cara penggunaan null
. Cara yang paling umum dan benar secara semantik adalah menggunakannya ketika Anda mungkin atau mungkin tidak memiliki nilai tunggal . Dalam hal ini nilai sama dengan null
atau adalah sesuatu yang bermakna seperti catatan dari database atau sesuatu.
Dalam situasi ini, Anda lebih sering menggunakannya seperti ini (dalam pseudo-code):
if (value is null) {
doSomethingAboutIt();
return;
}
doSomethingUseful(value);
Masalah
Dan itu memiliki masalah yang sangat besar. Masalahnya adalah pada saat Anda meminta doSomethingUseful
nilainya mungkin belum diperiksa null
! Jika tidak maka program kemungkinan akan macet. Dan pengguna bahkan mungkin tidak melihat pesan kesalahan yang baik, dibiarkan dengan sesuatu seperti "kesalahan mengerikan: nilai yang diinginkan tetapi mendapat nol!" (setelah pembaruan: meskipun mungkin ada kesalahan yang kurang informatif seperti Segmentation fault. Core dumped.
, atau lebih buruk lagi, tidak ada kesalahan dan manipulasi salah pada null dalam beberapa kasus)
Lupa menulis cek null
dan menangani null
situasi adalah bug yang sangat umum . Inilah sebabnya mengapa Tony Hoare yang menemukan null
mengatakan pada konferensi perangkat lunak bernama QCon London pada 2009 bahwa ia membuat kesalahan miliaran dolar pada tahun 1965:
https://www.infoq.com/presentations/Null-References-The-Billion-Dollar- Kesalahan-Tony-Hoare
Menghindari masalah
Beberapa teknologi dan bahasa membuat pengecekan null
tidak mungkin dilupakan dengan cara yang berbeda, mengurangi jumlah bug.
Misalnya Haskell memiliki Maybe
monad bukan nol. Misalkan DatabaseRecord
adalah tipe yang ditentukan pengguna. Dalam Haskell nilai tipe Maybe DatabaseRecord
bisa sama Just <somevalue>
atau mungkin sama dengan Nothing
. Anda kemudian dapat menggunakannya dengan cara yang berbeda tetapi tidak peduli bagaimana Anda menggunakannya, Anda tidak dapat menerapkan beberapa operasi Nothing
tanpa menyadarinya.
Misalnya fungsi ini disebut zeroAsDefault
pengembalian x
untuk Just x
dan 0
untuk Nothing
:
zeroAsDefault :: Maybe Int -> Int
zeroAsDefault mx = case mx of
Nothing -> 0
Just x -> x
Christian Hackl mengatakan C ++ 17 dan Scala memiliki cara mereka sendiri. Jadi, Anda mungkin ingin mencoba mencari tahu apakah bahasa Anda memiliki sesuatu seperti itu dan menggunakannya.
Nulls masih digunakan secara luas
Jika Anda tidak memiliki yang lebih baik maka menggunakan null
itu tidak masalah. Tetap waspada untuk itu. Ketik deklarasi dalam fungsi akan sedikit membantu Anda.
Mungkin itu kedengarannya tidak terlalu progresif tetapi Anda harus memeriksa apakah rekan kerja Anda ingin menggunakan null
atau sesuatu yang lain. Mereka mungkin konservatif dan mungkin tidak ingin menggunakan struktur data baru karena beberapa alasan. Misalnya mendukung versi bahasa yang lebih lama. Hal-hal seperti itu harus dinyatakan dalam standar pengkodean proyek dan didiskusikan dengan baik dengan tim.
Atas proposal Anda
Anda menyarankan menggunakan bidang boolean yang terpisah. Tetapi Anda harus memeriksanya dan mungkin masih lupa untuk memeriksanya. Jadi tidak ada yang menang di sini. Jika Anda bahkan dapat melupakan sesuatu yang lain, seperti memperbarui kedua nilai setiap kali, maka itu lebih buruk lagi. Jika masalah lupa untuk memeriksa null
tidak terpecahkan maka tidak ada gunanya. Menghindari null
itu sulit dan Anda seharusnya tidak melakukannya sedemikian rupa sehingga membuatnya lebih buruk.
Bagaimana tidak menggunakan null
Akhirnya ada cara umum untuk menggunakan secara null
tidak benar. Salah satu cara adalah menggunakannya di tempat struktur data kosong seperti array dan string. Array kosong adalah array yang tepat seperti yang lainnya! Itu hampir selalu penting dan berguna untuk struktur data, yang dapat memuat banyak nilai, untuk dapat kosong, yaitu memiliki 0 panjang.
Dari sudut pandang aljabar, string kosong untuk string sama seperti 0 untuk angka, yaitu identitas:
a+0=a
concat(str, '')=str
String kosong memungkinkan string secara umum menjadi monoid:
https://en.wikipedia.org/wiki/Monoid
Jika Anda tidak mendapatkannya, itu tidak penting bagi Anda.
Sekarang mari kita lihat mengapa penting untuk pemrograman dengan contoh ini:
for (element in array) {
doSomething(element);
}
Jika kita melewatkan array kosong di sini kode akan berfungsi dengan baik. Itu tidak akan melakukan apa-apa. Namun jika kita melewati di null
sini maka kita kemungkinan akan mengalami crash dengan kesalahan seperti "tidak dapat melewati null, maaf". Kita bisa membungkusnya if
tetapi itu kurang bersih dan lagi, Anda mungkin lupa memeriksanya
Cara menangani null
Apa yang doSomethingAboutIt()
harus dilakukan dan terutama apakah harus mengeluarkan pengecualian adalah masalah rumit lainnya. Singkatnya itu tergantung pada apakah null
nilai input yang dapat diterima untuk tugas yang diberikan dan apa yang diharapkan sebagai respons. Pengecualian untuk acara yang tidak diharapkan. Saya tidak akan masuk lebih jauh ke topik itu. Jawaban ini sudah sangat lama.
std::optional
atauOption
. Dalam bahasa lain, Anda mungkin harus membangun mekanisme yang tepat sendiri, atau Anda mungkin benar-benar menggunakannull
atau sesuatu yang serupa karena lebih idiomatik.