Inti pertanyaannya adalah "Bagaimana cara mengembalikan dua informasi yang tidak terkait dari metode yang mengembalikan satu int? Saya tidak pernah ingin memeriksa nilai pengembalian saya, dan nol itu buruk, jangan gunakan mereka."
Mari kita lihat apa yang ingin Anda lewati. Anda lewat baik int, atau non-int alasan mengapa Anda tidak bisa memberikan int. Pertanyaan itu menegaskan bahwa hanya akan ada dua alasan, tetapi siapa pun yang pernah membuat enum tahu bahwa daftar apa pun akan tumbuh. Cakupan untuk menentukan alasan lain masuk akal.
Awalnya, kemudian, ini sepertinya kasus yang baik untuk melempar pengecualian.
Ketika Anda ingin memberi tahu penelepon sesuatu yang istimewa yang tidak ada dalam tipe pengembalian, pengecualian seringkali merupakan sistem yang sesuai: pengecualian tidak hanya untuk status kesalahan, dan memungkinkan Anda untuk mengembalikan banyak konteks dan alasan untuk menjelaskan mengapa Anda hanya bisa hari ini.
Dan ini adalah sistem HANYA yang memungkinkan Anda untuk mengembalikan int yang dijamin-valid, dan menjamin bahwa setiap operator int dan metode yang mengambil int dapat menerima nilai pengembalian metode ini tanpa perlu memeriksa nilai yang tidak valid seperti nilai null, atau nilai sihir.
Tetapi pengecualian benar-benar hanya solusi yang valid jika, seperti namanya, ini adalah kasus luar biasa , bukan bisnis normal.
Dan coba / tangkap dan pawang sama seperti boilerplate sebagai cek nol, yang adalah apa yang pertama kali keberatan.
Dan jika penelepon tidak berisi try / catch, maka penelepon harus, dan seterusnya.
Lulus kedua yang naif adalah mengatakan "Ini pengukuran. Pengukuran jarak negatif tidak mungkin." Jadi untuk beberapa pengukuran Y, Anda bisa memiliki konstanta untuk
- -1 = tidak diketahui,
- -2 = tidak mungkin untuk diukur,
- -3 = menolak untuk menjawab,
- -4 = diketahui tetapi rahasia,
- -5 = bervariasi tergantung pada fase bulan, lihat tabel 5a,
- -6 = empat dimensi, pengukuran diberikan dalam judul,
- -7 = kesalahan pembacaan sistem file,
- -8 = dicadangkan untuk penggunaan di masa mendatang,
- -9 = kuadrat / kubik jadi Y sama dengan X,
- -10 = adalah layar monitor jadi tidak menggunakan pengukuran X, Y: gunakan X sebagai layar diagonal,
- -11 = menulis pengukuran di belakang tanda terima dan dicuci menjadi tidak terbaca tetapi saya pikir itu 5 atau 17,
- -12 = ... Anda mendapatkan ide.
Ini adalah cara yang dilakukan dalam banyak sistem C lama, dan bahkan dalam sistem modern di mana ada kendala asli untuk int, dan Anda tidak dapat membungkusnya dengan struct atau monad dari beberapa jenis.
Jika pengukuran bisa negatif, maka Anda hanya membuat tipe data Anda lebih besar (mis. Int panjang) dan memiliki nilai ajaib lebih tinggi dari kisaran int, dan idealnya dimulai dengan beberapa nilai yang akan muncul dengan jelas dalam debugger.
Ada alasan bagus untuk menjadikannya sebagai variabel terpisah, alih-alih hanya memiliki angka ajaib. Misalnya, pengetikan yang ketat, rawatan, dan sesuai dengan harapan.
Maka, dalam upaya ketiga kami, kami melihat kasus-kasus di mana bisnis normal memiliki nilai non-int. Misalnya, jika kumpulan nilai-nilai ini dapat berisi beberapa entri non-integer. Ini berarti penangan pengecualian mungkin pendekatan yang salah.
Dalam hal itu, terlihat kasus yang bagus untuk struktur yang melewati int, dan alasannya. Sekali lagi, alasan ini bisa saja merupakan konstelasi seperti di atas, tetapi alih-alih memegang keduanya di int yang sama, Anda menyimpannya sebagai bagian yang berbeda dari suatu struktur. Awalnya, kami memiliki aturan bahwa jika alasannya diatur, int tidak akan ditetapkan. Tetapi kita tidak lagi terikat pada aturan ini; kami dapat memberikan alasan untuk angka yang valid juga, jika perlu.
Either way, setiap kali Anda menyebutnya, Anda masih memerlukan boilerplate, untuk menguji alasan untuk melihat apakah int itu valid, lalu tarik keluar dan gunakan bagian int jika alasannya memungkinkan kami.
Di sinilah Anda perlu menyelidiki alasan Anda di balik "jangan gunakan null".
Seperti halnya pengecualian, null dimaksudkan untuk menandakan keadaan luar biasa.
Jika penelepon memanggil metode ini dan mengabaikan bagian "rasional" dari struktur sepenuhnya, mengharapkan nomor tanpa penanganan kesalahan, dan mendapat nol, maka itu akan menangani nol sebagai angka, dan salah. Jika mendapat nomor ajaib, itu akan memperlakukannya sebagai angka, dan salah. Tetapi jika mendapat nol, itu akan jatuh , seperti yang seharusnya dilakukan.
Jadi setiap kali Anda memanggil metode ini, Anda harus memasukkan cek untuk nilai pengembaliannya, namun Anda menangani nilai-nilai yang tidak valid, baik dalam-band atau keluar dari band, mencoba / menangkap, memeriksa struct untuk komponen "rasional", memeriksa int untuk nomor ajaib, atau memeriksa int untuk null ...
Alternatifnya, untuk menangani multiplikasi output yang mungkin mengandung int tidak valid dan alasan seperti "Anjing saya memakan pengukuran ini", adalah membebani operator multiplikasi untuk struktur itu.
... Dan kemudian membebani setiap operator lain dalam aplikasi Anda yang mungkin diterapkan pada data ini.
... Dan kemudian membebani semua metode yang mungkin memerlukan int.
... Dan semua kelebihan itu masih harus mengandung cek untuk int yang tidak valid, hanya agar Anda dapat memperlakukan jenis pengembalian metode yang satu ini seolah-olah itu selalu int yang valid pada saat Anda meneleponnya.
Jadi premis aslinya salah dalam berbagai cara:
- Jika Anda memiliki nilai yang tidak valid, Anda tidak dapat menghindari memeriksa nilai-nilai yang tidak valid di setiap titik dalam kode tempat Anda menangani nilai-nilai tersebut.
- Jika Anda mengembalikan sesuatu selain int, Anda tidak mengembalikan int, sehingga Anda tidak dapat memperlakukannya seperti int. Kelebihan operator memungkinkan Anda berpura - pura , tapi itu hanya pura-pura.
- Int dengan angka ajaib (termasuk NULL, NAN, Inf ...) tidak lagi benar-benar int, ini adalah struct orang miskin.
- Menghindari nulls tidak akan membuat kode lebih kuat, itu hanya akan menyembunyikan masalah dengan ints, atau memindahkannya ke dalam struktur penanganan pengecualian yang kompleks.