Ini adalah salah satu aturan yang berulang kali berulang dan membingungkan saya.
Null adalah kejahatan dan harus dihindari sedapat mungkin .
Tapi, tapi - dari kenaifan saya, izinkan saya menjerit - kadang-kadang nilai BISA tidak ada!
Tolong izinkan saya bertanya ini pada contoh yang berasal dari kode mengerikan anti-pola ditunggangi saya sedang mengerjakan saat ini . Ini adalah, pada intinya, permainan berbasis web multiplayer, di mana giliran kedua pemain dijalankan secara bersamaan (seperti di Pokemon, dan sebaliknya untuk Catur).
Setelah setiap belokan, server menyiarkan daftar pembaruan ke kode JS sisi klien. Kelas Pembaruan:
public class GameUpdate
{
public Player player;
// other stuff
}
Kelas ini diserialisasi ke JSON dan dikirim ke pemain yang terhubung.
Sebagian besar pembaruan secara alami memiliki Player yang terkait dengannya - lagipula, perlu diketahui pemain mana yang melakukan perubahan ini. Namun, beberapa pembaruan tidak dapat memiliki Pemain yang terkait secara bermakna dengannya. Contoh: Permainan telah diikat secara paksa karena batas belok tanpa tindakan telah terlampaui. Untuk pembaruan seperti itu, saya pikir, sangat berarti memiliki pemain dibatalkan.
Tentu saja, saya bisa "memperbaiki" kode ini dengan memanfaatkan pewarisan:
public class GameUpdate
{
// stuff
}
public class GamePlayerUpdate : GameUpdate
{
public Player player;
// other stuff
}
Namun, saya gagal melihat bagaimana ini merupakan peningkatan, karena dua alasan:
- Kode JS sekarang hanya akan menerima objek tanpa Player sebagai properti yang ditentukan, yang sama seperti jika itu nol karena kedua kasus memerlukan pemeriksaan apakah nilainya ada atau tidak;
- Jika bidang nullable lainnya ditambahkan ke kelas GameUpdate, saya harus dapat menggunakan banyak pewarisan untuk melanjutkan desing ini - tetapi MI itu jahat dalam dirinya sendiri (menurut programmer yang lebih berpengalaman) dan yang lebih penting, C # tidak memilikinya jadi saya tidak bisa menggunakannya.
Saya punya firasat bahwa bagian dari kode ini adalah salah satu dari sekian banyak di mana seorang programmer yang baik dan berpengalaman akan berteriak ngeri. Pada saat yang sama saya tidak bisa melihat bagaimana, di tempat ini, apakah ini nol menyakiti apa pun dan apa yang harus dilakukan sebagai gantinya.
Bisakah Anda menjelaskan masalah ini kepada saya?
sumber
Jawaban:
Banyak hal yang lebih baik untuk dikembalikan daripada nol.
(yang membuat Anda dianggap nol sejak awal)
Kuncinya adalah menyadari kapan harus melakukan ini. Null benar-benar bagus dalam meledakkan di wajah Anda, tetapi hanya ketika Anda dot off tanpa memeriksanya. Tidak bagus menjelaskan mengapa.
Ketika Anda tidak perlu meledak, dan Anda tidak ingin memeriksa nol, gunakan salah satu dari alternatif ini. Mungkin aneh untuk mengembalikan koleksi jika hanya memiliki 0 atau 1 elemen, tetapi sangat bagus untuk membiarkan Anda secara diam-diam menangani nilai yang hilang.
Monads terdengar mewah tetapi di sini yang mereka lakukan hanyalah membiarkan Anda memperjelas bahwa ukuran yang valid untuk koleksi adalah 0 dan 1. Jika Anda memilikinya, pertimbangkanlah.
Semua ini melakukan pekerjaan yang lebih baik untuk membuat maksud Anda lebih jelas daripada null. Itulah perbedaan terpenting.
Mungkin membantu untuk memahami mengapa Anda kembali sama sekali daripada hanya melemparkan pengecualian. Pengecualian pada dasarnya adalah cara untuk menolak asumsi (mereka bukan satu-satunya cara). Ketika Anda meminta titik di mana dua garis berpotongan Anda mengasumsikan mereka berpotongan. Mereka mungkin paralel. Haruskah Anda melemparkan pengecualian "garis paralel"? Yah Anda bisa, tetapi sekarang Anda harus menangani pengecualian itu di tempat lain atau membiarkannya menghentikan sistem.
Jika Anda lebih suka tinggal di tempat Anda berada, Anda dapat memanggang penolakan terhadap asumsi itu menjadi semacam nilai yang dapat mengekspresikan hasil atau penolakan. Itu tidak aneh. Kami melakukannya dalam aljabar sepanjang waktu. Triknya adalah menjadikan nilai itu bermakna sehingga kita dapat memahami apa yang terjadi.
Jika nilai yang dikembalikan dapat mengekspresikan hasil dan penolakan, maka perlu dikirim ke kode yang dapat menangani keduanya. Polimorfisme sangat kuat untuk digunakan di sini. Daripada hanya memperdagangkan cek kosong untuk
isPresent()
cek, Anda dapat menulis kode yang berperilaku baik. Baik dengan mengganti nilai kosong dengan nilai default atau diam-diam tidak melakukan apa pun.Masalah dengan null adalah bisa berarti terlalu banyak hal. Jadi itu hanya menghancurkan informasi.
Dalam eksperimen tanpa pikiran favorit saya, saya meminta Anda membayangkan mesin Rube Goldbergian kompleks yang memberi sinyal pesan yang disandikan menggunakan cahaya berwarna dengan mengambil bola lampu berwarna dari sabuk konveyor, memasukkannya ke dalam soket, dan menyalakannya. Sinyal dikontrol oleh berbagai warna bohlam yang ditempatkan pada ban berjalan.
Anda telah diminta untuk membuat hal yang sangat mahal ini sesuai dengan RFC3.14159 yang menyatakan bahwa harus ada penanda di antara pesan-pesan. Penanda seharusnya tidak ada cahaya sama sekali. Itu harus berlangsung tepat satu pulsa. Jumlah waktu yang sama dengan cahaya satu warna biasanya bersinar.
Anda tidak dapat meninggalkan ruang di antara pesan karena alat ini mematikan alarm dan berhenti jika tidak menemukan bohlam untuk dimasukkan ke dalam soket.
Semua orang yang akrab dengan proyek ini ngeri saat menyentuh mesin atau itu kode kontrol. Tidak mudah untuk berubah. Apa yang kamu kerjakan? Anda bisa menyelam dan mulai merusak barang-barang. Mungkin memperbarui hal-hal ini desain yang mengerikan. Ya Anda bisa membuatnya jauh lebih baik. Atau Anda bisa berbicara dengan petugas kebersihan dan mulai mengumpulkan umbi yang terbakar.
Itu solusi polimorfik. Sistem bahkan tidak perlu tahu ada yang berubah.
Sangat menyenangkan jika Anda bisa melakukannya. Dengan menyandikan penolakan bermakna terhadap asumsi menjadi nilai, Anda tidak perlu memaksakan pertanyaan untuk berubah.
Berapa banyak apel yang akan Anda beri saya jika saya memberi Anda 1 apel? -1. Karena aku berutang 2 apel padamu dari kemarin. Di sini asumsi pertanyaan, "Anda akan berutang padaku", ditolak dengan angka negatif. Meskipun pertanyaannya salah, info yang bermakna disandikan dalam jawaban ini. Dengan menolaknya dengan cara yang berarti pertanyaan itu tidak dipaksa untuk berubah.
Namun, terkadang mengubah pertanyaan sebenarnya adalah jalan yang harus ditempuh. Jika asumsi dapat dibuat lebih dapat diandalkan, sementara masih bermanfaat, pertimbangkan untuk melakukannya.
Masalah Anda adalah, biasanya, pembaruan datang dari pemain. Tetapi Anda telah menemukan kebutuhan untuk pembaruan yang tidak datang dari pemain 1 atau pemain 2. Anda perlu pembaruan yang mengatakan waktu telah kedaluwarsa. Tidak ada pemain yang mengatakan ini, jadi apa yang harus Anda lakukan? Meninggalkan pemain null sepertinya sangat menggoda. Tetapi itu menghancurkan informasi. Anda mencoba menyandikan pengetahuan dalam lubang hitam.
Bidang pemain tidak memberi tahu Anda yang baru saja pindah. Anda pikir memang demikian, tetapi masalah ini membuktikan bahwa itu bohong. Bidang pemain memberi tahu Anda dari mana pembaruan itu berasal. Pembaruan waktu kedaluwarsa Anda datang dari jam permainan. Rekomendasi saya adalah memberi jam kredit yang layak dan mengubah nama
player
bidang menjadi sesuatu sepertisource
.Dengan cara ini jika server dimatikan dan harus menangguhkan permainan, ia dapat mengirimkan pembaruan yang melaporkan apa yang terjadi dan mencantumkan dirinya sebagai sumber pembaruan.
Apakah ini berarti Anda tidak boleh meninggalkan sesuatu begitu saja? Tidak. Tapi Anda perlu mempertimbangkan seberapa baik tidak ada yang dapat dianggap benar-benar berarti satu nilai standar baik yang terkenal. Tidak ada yang benar-benar mudah digunakan secara berlebihan. Jadi berhati-hatilah saat Anda menggunakannya. Ada sebuah mazhab pemikiran yang mencakup tidak mendukung apa pun . Ini disebut konvensi atas konfigurasi .
Saya suka itu sendiri tetapi hanya ketika konvensi jelas dikomunikasikan dalam beberapa cara. Seharusnya bukan cara untuk kabut pemula. Tetapi bahkan jika Anda menggunakannya, null masih bukan cara terbaik untuk melakukannya. Null adalah berbahaya apa-apa . Null berpura-pura menjadi sesuatu yang dapat Anda gunakan sampai Anda menggunakannya, lalu ia menghancurkan lubang di alam semesta (menghancurkan model semantik Anda). Kecuali jika meniup lubang di alam semesta adalah perilaku yang Anda butuhkan, mengapa Anda mengacaukan ini? Gunakan sesuatu yang lain.
sumber
null
sebenarnya bukan masalah di sini. Masalahnya adalah bagaimana kebanyakan bahasa pemrograman saat ini menangani informasi yang hilang; mereka tidak menganggap serius masalah ini (atau setidaknya tidak memberikan dukungan dan keamanan yang paling dibutuhkan oleh penduduk bumi untuk menghindari perangkap). Ini mengarah ke semua masalah yang telah kita pelajari untuk ditakuti (Javas NullPointerException, Segfaults, ...).Mari kita lihat bagaimana menangani masalah itu dengan cara yang lebih baik.
Lainnya menyarankan Pola Null-Object . Meskipun saya pikir itu kadang-kadang berlaku, ada banyak skenario di mana tidak ada nilai standar satu ukuran untuk semua. Dalam kasus tersebut, konsumen dari informasi yang mungkin tidak hadir harus dapat memutuskan sendiri apa yang harus dilakukan jika informasi tersebut hilang.
Ada bahasa pemrograman yang memberikan keamanan terhadap null pointer (disebut void safety) pada waktu kompilasi. Untuk memberikan beberapa contoh modern: Kotlin, Rust, Swift. Dalam bahasa tersebut, masalah informasi yang hilang telah dianggap serius dan menggunakan null benar-benar tidak menimbulkan rasa sakit - kompiler akan menghentikan Anda dari mendereferensi nullpointers.
Di Jawa, upaya telah dilakukan untuk membuat anotasi @ Nullable / @ NotNull bersama-sama dengan plugin compiler + IDE untuk mencapai efek yang sama. Itu tidak benar-benar berhasil tetapi itu di luar jangkauan untuk jawaban ini.
Tipe eksplisit dan generik yang menunjukkan kemungkinan tidak ada adalah cara lain untuk menghadapinya. Misal di Jawa ada
java.util.Optional
. Ini dapat bekerja:Pada tingkat proyek atau perusahaan, Anda dapat menetapkan aturan / pedoman
java.util.Optional
bukannull
Komunitas / ekosistem bahasa Anda mungkin telah menemukan cara lain untuk mengatasi masalah ini dengan lebih baik daripada kompiler / penerjemah.
sumber
Optional.isPresent
isPresent()
bukan penggunaan Opsional yangSaya tidak melihat ada kelebihan dalam pernyataan bahwa null itu buruk. Saya memeriksa diskusi tentang hal itu dan mereka hanya membuat saya tidak sabar dan jengkel.
Null dapat digunakan salah, sebagai "nilai ajaib", ketika itu sebenarnya berarti sesuatu. Tetapi Anda harus melakukan beberapa pemrograman yang cukup memutar untuk sampai ke sana.
Null harus berarti "tidak ada", yang belum dibuat (belum) atau hilang (sudah) atau tidak tersedia jika itu argumen. Ini bukan keadaan, semuanya hilang. Dalam pengaturan OO di mana segala sesuatu dibuat dan dihancurkan sepanjang waktu yang merupakan kondisi yang valid dan bermakna berbeda dari negara bagian mana pun.
Tidak sepenuhnya benar, saya bisa mendapatkan peringatan untuk tidak memeriksa nol sebelum menggunakan variabel. Dan itu tidak sama. Saya mungkin tidak ingin menyimpan sumber daya dari suatu objek yang tidak memiliki tujuan. Dan yang lebih penting, saya harus memeriksa alternatif yang sama untuk mendapatkan perilaku yang diinginkan. Jika saya lupa melakukan itu saya lebih suka mendapatkan NullReferenceException saat runtime daripada beberapa perilaku yang tidak ditentukan / tidak diinginkan.
Ada satu masalah yang harus diperhatikan. Dalam konteks multi-utas Anda harus melindungi terhadap kondisi balapan dengan menugaskan variabel lokal terlebih dahulu sebelum melakukan pemeriksaan untuk nol.
Tidak, itu tidak / seharusnya tidak berarti apa-apa sehingga tidak ada yang bisa dihancurkan. Nama dan tipe variabel / argumen akan selalu memberi tahu apa yang hilang, hanya itu yang perlu diketahui.
Edit:
Saya setengah dari video yang di- link oleh candied_orange di salah satu jawaban lainnya tentang pemrograman fungsional dan ini sangat menarik. Saya bisa melihat manfaatnya dalam skenario tertentu. Pendekatan fungsional yang telah saya lihat sejauh ini, dengan potongan-potongan kode terbang di sekitar, biasanya membuat saya ngeri ketika digunakan dalam pengaturan OO. Tapi saya kira tempatnya. Di suatu tempat. Dan saya kira akan ada bahasa yang melakukan pekerjaan dengan baik menyembunyikan apa yang saya anggap sebagai kekacauan yang membingungkan setiap kali saya menemukannya di C #, bahasa yang menyediakan model yang bersih dan bisa diterapkan sebagai gantinya.
Jika model fungsional itu adalah pola pikir / kerangka kerja Anda, benar-benar tidak ada alternatif untuk mendorong kesalahan apa pun ke depan sebagai deskripsi kesalahan yang terdokumentasi dan pada akhirnya membiarkan penelepon berurusan dengan akumulasi sampah yang diseret sepanjang jalan kembali ke titik inisiasi. Rupanya ini hanya cara kerja pemrograman fungsional. Sebut saja batasan, sebut saja paradigma baru. Anda mungkin menganggapnya sebagai peretasan untuk murid fungsional yang memungkinkan mereka untuk melanjutkan di jalan yang tidak suci sedikit lebih jauh, Anda mungkin senang dengan cara pemrograman baru ini yang melepaskan kemungkinan baru yang menarik. Apa pun, tampaknya tidak ada gunanya bagi saya untuk melangkah ke dunia itu, kembali ke cara tradisional OO dalam melakukan sesuatu (ya, kita bisa melempar pengecualian, maaf), mengambil beberapa konsep darinya,
Konsep apa pun bisa digunakan dengan cara yang salah. Dari tempat saya berdiri, "solusi" yang disajikan bukanlah alternatif untuk penggunaan null yang tepat. Mereka adalah konsep dari dunia lain.
sumber
None
mewakili….Pertanyaanmu.
Sepenuhnya dengan Anda di sana. Namun, ada beberapa peringatan yang akan saya bahas dalam sedetik. Tapi pertama-tama:
Saya pikir ini adalah pernyataan yang bermaksud baik tetapi terlalu umum.
Null bukanlah kejahatan. Mereka bukan antipattern. Mereka bukan sesuatu yang harus dihindari bagaimanapun caranya. Namun, nol adalah cenderung rentan terhadap kesalahan (karena gagal memeriksa nol).
Tapi saya tidak mengerti bagaimana kegagalan untuk memeriksa null adalah bukti bahwa null secara inheren salah untuk digunakan.
Jika null jahat, maka indeks array dan pointer C ++ juga sama. Mereka tidak. Mereka mudah menembak diri sendiri dengan kaki, tetapi mereka tidak seharusnya dihindari dengan cara apa pun.
Untuk sisa jawaban ini, saya akan menyesuaikan niat "nulls are evil" ke yang lebih bernuansa " nulls harus ditangani secara bertanggung jawab ".
Solusi Anda.
Sementara saya setuju dengan pendapat Anda tentang penggunaan null sebagai aturan global; Saya tidak setuju dengan penggunaan nol Anda dalam kasus khusus ini.
Untuk meringkas umpan balik di bawah ini: Anda salah memahami tujuan pewarisan dan polimorfisme. Sementara argumen Anda untuk menggunakan null memiliki validitas, "bukti" selanjutnya tentang mengapa cara lain yang buruk dibangun di atas penyalahgunaan warisan, menjadikan poin Anda agak tidak relevan dengan masalah nol.
Jika pembaruan ini berbeda bermakna (yang mana), maka Anda memerlukan dua jenis pembaruan yang terpisah.
Pertimbangkan pesan, misalnya. Anda memiliki pesan kesalahan dan pesan obrolan IM. Tetapi sementara mereka mungkin berisi data yang sangat mirip (pesan string dan pengirim), mereka tidak berperilaku dengan cara yang sama. Mereka harus digunakan secara terpisah, sebagai kelas yang berbeda.
Apa yang Anda lakukan sekarang adalah membedakan secara efektif antara dua jenis pembaruan berdasarkan kekosongan properti Player. Itu sama dengan memutuskan antara pesan IM dan pesan kesalahan berdasarkan keberadaan kode kesalahan. Itu bekerja, tapi itu bukan pendekatan terbaik.
Argumen Anda bergantung pada kesalahan polimorfisme. Jika Anda memiliki metode yang mengembalikan
GameUpdate
objek, umumnya tidak perlu peduli untuk membedakanGameUpdate
,PlayerGameUpdate
atauNewlyDevelopedGameUpdate
.Kelas dasar harus memiliki kontrak yang berfungsi penuh, yaitu propertinya didefinisikan pada kelas dasar dan bukan pada kelas turunan (yang dikatakan, nilai properti-properti dasar ini tentu saja dapat ditimpa dalam kelas turunan).
Ini membuat argumen Anda bisa diperdebatkan. Dalam praktik yang baik, Anda tidak boleh peduli bahwa
GameUpdate
objek Anda memiliki atau tidak memiliki pemain. Jika Anda mencoba mengaksesPlayer
properti aGameUpdate
, maka Anda melakukan sesuatu yang tidak masuk akal.Bahasa yang diketik seperti C # bahkan tidak akan memungkinkan Anda untuk mencoba dan mengakses
Player
propertiGameUpdate
karenaGameUpdate
tidak memiliki properti. Javascript jauh lebih longgar dalam pendekatannya (dan tidak memerlukan prakompilasi) sehingga Javascript tidak repot-repot mengoreksi Anda dan malah membuatnya meledak saat runtime.Anda seharusnya tidak membuat kelas berdasarkan penambahan properti yang dapat dibatalkan. Anda harus membuat kelas berdasarkan jenis pembaruan game yang unik dan fungsional .
Bagaimana cara menghindari masalah dengan null secara umum?
Saya pikir itu relevan untuk menguraikan bagaimana Anda dapat secara bermakna mengekspresikan tidak adanya nilai. Ini adalah kumpulan solusi (atau pendekatan buruk) tanpa urutan tertentu.
1. Tetap gunakan null.
Ini adalah pendekatan termudah. Namun, Anda mendaftar sendiri untuk satu ton cek nol dan (ketika gagal melakukannya) pemecahan masalah pengecualian referensi nol.
2. Gunakan nilai tidak berarti yang bukan nol
Contoh sederhana di sini adalah
indexOf()
:Alih-alih
null
, Anda dapatkan-1
. Pada tingkat teknis, ini adalah nilai integer yang valid. Namun, nilai negatif adalah jawaban yang tidak masuk akal karena indeks diharapkan bilangan bulat positif.Secara logis, ini hanya dapat digunakan untuk kasus-kasus di mana tipe pengembalian memungkinkan nilai-nilai yang lebih mungkin daripada yang dapat dikembalikan secara bermakna (indexOf = bilangan bulat positif; int = bilangan bulat positif dan positif)
Untuk jenis referensi, Anda masih bisa menerapkan prinsip ini. Misalnya, jika Anda memiliki entitas dengan ID integer, Anda bisa mengembalikan objek dummy dengan ID yang disetel ke -1, sebagai kebalikan dari nol.
Anda hanya perlu mendefinisikan "dummy state" di mana Anda dapat mengukur apakah suatu objek benar-benar dapat digunakan atau tidak.
Perhatikan bahwa Anda tidak harus bergantung pada nilai string yang telah ditentukan jika Anda tidak mengontrol nilai string. Anda mungkin mempertimbangkan untuk menetapkan nama pengguna ke "null" ketika Anda ingin mengembalikan objek kosong, tetapi Anda akan mengalami masalah ketika Christopher Null mendaftar untuk layanan Anda .
3. Lempar pengecualian sebagai gantinya.
Tidak, tidak. Pengecualian tidak harus ditangani untuk aliran logis.
Yang sedang berkata, ada beberapa kasus di mana Anda tidak ingin menyembunyikan pengecualian (nullreference), tetapi menunjukkan pengecualian yang sesuai. Sebagai contoh:
Ini bisa melempar
PersonNotFoundException
(atau serupa) ketika tidak ada orang dengan ID 123.Agak jelas, ini hanya dapat diterima untuk kasus-kasus di mana tidak menemukan item membuat mustahil untuk melakukan pemrosesan lebih lanjut. Jika tidak menemukan item mungkin dan aplikasi dapat dilanjutkan, maka Anda TIDAK PERNAH harus melemparkan pengecualian . Saya tidak bisa cukup menekankan hal ini.
sumber
Titik mengapa null buruk adalah bahwa nilai yang hilang dikodekan sebagai nol, tetapi nilai referensi apa pun bisa menjadi nol. Jika Anda memiliki C #, Anda mungkin masih kalah. Saya tidak melihat poin untuk menggunakan beberapa Opsional di sana karena jenis referensi sudah opsional. Tetapi untuk Java ada anotasi @Notnull, yang tampaknya dapat Anda atur di tingkat paket , kemudian untuk nilai yang bisa dilewatkan Anda bisa menggunakan anotasi @Nullable.
sumber
Nulls bukanlah kejahatan, secara realistis tidak ada cara untuk mengimplementasikan salah satu alternatif tanpa pada titik tertentu berurusan dengan sesuatu yang terlihat seperti nol.
Namun, Nulls berbahaya . Sama seperti konstruksi tingkat rendah lainnya jika Anda salah tidak ada yang di bawah ini untuk menangkap Anda.
Saya pikir ada banyak argumen yang valid terhadap null:
Bahwa jika Anda sudah berada di domain tingkat tinggi, ada pola yang lebih aman daripada menggunakan model tingkat rendah.
Kecuali jika Anda membutuhkan keunggulan sistem tingkat rendah dan siap untuk menjadi hati-hati yang cocok maka mungkin Anda tidak boleh menggunakan bahasa tingkat rendah.
dll ...
Ini semua valid dan selanjutnya tidak harus membuat upaya menulis getter dan setter dll dipandang sebagai alasan umum untuk tidak mengikuti saran itu. Tidak terlalu mengejutkan banyak programmer yang sampai pada kesimpulan bahwa nol itu berbahaya dan malas (kombinasi yang buruk!), Tetapi seperti begitu banyak nasihat "universal" lainnya, mereka tidak seuniversal yang diucapkan.
Orang-orang baik yang menulis bahasa itu berpikir mereka akan berguna bagi seseorang. Jika Anda memahami keberatan dan masih menganggapnya tepat untuk Anda, tidak ada orang lain yang akan tahu.
sumber
Java memiliki
Optional
kelas denganifPresent
+ lambda eksplisit untuk mengakses nilai apa pun dengan aman. Ini dapat dibuat di JS juga:Lihat pertanyaan StackOverflow ini .
By the way: banyak purist akan menemukan penggunaan ini meragukan, tapi saya rasa tidak. Fitur opsional memang ada.
sumber
java.lang.Optional
menjadinull
terlalu?Optional.of(null)
akan melempar pengecualian,Optional.ofNullable(null)
akan memberikanOptional.empty()
- nilai tidak ada.Optional<Type> a = null
?Optional<Optional<Type>> a = Optional.empty();
;) - Dengan kata lain dalam JS (dan bahasa lain) hal-hal seperti itu tidak akan layak. Scala dengan nilai default akan dilakukan. Jawa mungkin dengan enum. JS saya ragu:Optional<Type> a = Optional.empty();
.null
atau kosong, ke dua ditambah beberapa metode tambahan pada objek yang dimasukkan. Itu sebuah pencapaian.CAR Hoare menyebut nulls sebagai "kesalahan miliar dolar". Namun, penting untuk dicatat bahwa ia berpikir solusinya bukan "tidak ada null di mana saja" tetapi sebaliknya "pointer non-nullable sebagai default dan nulls hanya di mana mereka diperlukan secara semantik".
Masalah dengan null dalam bahasa yang mengulang kesalahannya adalah Anda tidak bisa mengatakan bahwa suatu fungsi mengharapkan data yang tidak dapat dibatalkan; itu pada dasarnya tidak bisa diungkapkan dalam bahasa. Yang memaksa fungsi untuk memasukkan banyak boilerplate null-handling asing yang tidak berguna, dan melupakan cek null adalah sumber umum bug.
Untuk meretas kurangnya ekspresi yang mendasar, beberapa komunitas (mis. Komunitas Scala) tidak menggunakan null. Dalam Scala, jika Anda menginginkan nilai tipe nullable
T
, Anda mengambil argumen tipeOption[T]
, dan jika Anda menginginkan nilai non-nullable, Anda hanya mengambil aT
. Jika seseorang memasukkan nol ke dalam kode Anda, kode Anda akan meledak. Namun, itu dianggap bahwa kode panggilan adalah kode kereta.Option
adalah pengganti yang cukup bagus untuk null, karena pola penanganan-nol yang umum diekstraksi ke fungsi perpustakaan seperti.map(f)
atau.getOrElse(someDefault)
.sumber