Saya datang dengan ini:
(defn string-> integer [str & [base]] (Integer / parseInt str (if (nil? Base) 10 base)))) (string-> integer "10") (string-> integer "FF" 16)
Tetapi ini harus menjadi cara yang lebih baik untuk melakukan ini.
Saya datang dengan ini:
(defn string-> integer [str & [base]] (Integer / parseInt str (if (nil? Base) 10 base)))) (string-> integer "10") (string-> integer "FF" 16)
Tetapi ini harus menjadi cara yang lebih baik untuk melakukan ini.
Suatu fungsi dapat memiliki beberapa tanda tangan jika tanda tangan berbeda dalam arity. Anda dapat menggunakannya untuk memberikan nilai default.
(defn string->integer
([s] (string->integer s 10))
([s base] (Integer/parseInt s base)))
Perhatikan bahwa asumsi false
dan nil
keduanya dianggap tidak bernilai, (if (nil? base) 10 base)
dapat disingkat menjadi (if base base 10)
, atau lebih jauh (or base 10)
.
(recur s 10)
, menggunakanrecur
alih-alih mengulangi nama fungsistring->integer
. Itu akan membuatnya lebih mudah untuk mengubah nama fungsi di masa depan. Adakah yang tahu alasan untuk tidak menggunakanrecur
dalam situasi ini?recur
hanya bekerja pada arity yang sama. jika Anda mencoba berulang di atas, misalnya:java.lang.IllegalArgumentException: Mismatched argument count to recur, expected: 1 args, got: 2, compiling:
(string->integer s 10)
)?Anda juga dapat merusak
rest
argumen sebagai peta sejak Clojure 1.2 [ ref ]. Ini memungkinkan Anda memberi nama dan memberikan default untuk argumen fungsi:Sekarang kamu bisa menelepon
atau
Anda dapat melihat ini dalam aksi di sini: https://github.com/Raynes/cl[/blob/master/src/cl[/core.clj (misalnya)
sumber
Solusi ini lebih dekat dengan semangat solusi asli , tetapi sedikit lebih bersih
Sebuah pola yang sama yang dapat menggunakan berguna
or
dikombinasikan denganlet
Meskipun dalam hal ini lebih banyak bertele-tele, ini dapat bermanfaat jika Anda ingin memiliki standar bergantung pada nilai input lainnya . Misalnya, pertimbangkan fungsi berikut:
Pendekatan ini dapat dengan mudah diperluas untuk bekerja dengan argumen bernama (seperti dalam solusi M. Gilliar) juga:
Atau menggunakan lebih banyak perpaduan:
sumber
or
or
berbeda dari:or
karenaor
tidak tahu perbedaannil
danfalse
.Ada pendekatan lain yang mungkin ingin Anda pertimbangkan: fungsi parsial . Ini bisa dibilang cara yang lebih "fungsional" dan lebih fleksibel untuk menentukan nilai default untuk fungsi.
Mulailah dengan membuat (jika perlu) fungsi yang memiliki parameter yang ingin Anda berikan sebagai default sebagai parameter utama:
Ini dilakukan karena versi Clojure
partial
memungkinkan Anda memberikan nilai "default" hanya dalam urutan yang muncul dalam definisi fungsi. Setelah parameter telah dipesan sesuai keinginan, Anda kemudian dapat membuat versi "default" dari fungsi menggunakanpartial
fungsi:Untuk membuat fungsi ini bisa dipanggil beberapa kali, Anda bisa meletakkannya di var menggunakan
def
:Anda juga dapat membuat "default lokal" menggunakan
let
:Pendekatan fungsi parsial memiliki satu keunggulan utama dibandingkan yang lain: konsumen fungsi masih dapat memutuskan apa nilai default akan menjadi daripada produsen fungsi tanpa perlu memodifikasi definisi fungsi . Ini diilustrasikan dalam contoh di
hex
mana saya telah memutuskan bahwa fungsi defaultdecimal
bukan yang saya inginkan.Keuntungan lain dari pendekatan ini adalah Anda dapat menetapkan fungsi default nama yang berbeda (desimal, hex, dll) yang mungkin lebih deskriptif dan / atau cakupan yang berbeda (var, lokal). Fungsi parsial juga dapat dicampur dengan beberapa pendekatan di atas jika diinginkan:
(Perhatikan ini sedikit berbeda dari jawaban Brian karena urutan parameter telah dibalik karena alasan yang diberikan di bagian atas respons ini)
sumber
Anda mungkin juga melihat ke
(fnil)
https://clojuredocs.org/clojure.core/fnilsumber