Przychodzę z tym:
(defn string-> integer [str & [base]] (Integer / parseInt str (if (nil? Base) 10 base))) (ciąg-> liczba całkowita "10") (ciąg-> liczba całkowita "FF" 16)
Ale to musi być lepszy sposób na zrobienie tego.
Przychodzę z tym:
(defn string-> integer [str & [base]] (Integer / parseInt str (if (nil? Base) 10 base))) (ciąg-> liczba całkowita "10") (ciąg-> liczba całkowita "FF" 16)
Ale to musi być lepszy sposób na zrobienie tego.
Funkcja może mieć wiele podpisów, jeśli sygnatury różnią się pod względem liczby. Możesz użyć tego do podania wartości domyślnych.
(defn string->integer
([s] (string->integer s 10))
([s base] (Integer/parseInt s base)))
Zauważ, że założenie false
i nil
oba są uważane za nie-wartości, (if (nil? base) 10 base)
można skrócić do (if base base 10)
lub dalej do (or base 10)
.
(recur s 10)
, używającrecur
zamiast powtarzać nazwę funkcjistring->integer
. Ułatwiłoby to w przyszłości zmianę nazwy funkcji. Czy ktoś zna jakiś powód, aby nie używaćrecur
w takich sytuacjach?recur
działa tylko na tej samej mocy. jeśli próbowałeś powtórzyć powyżej, na przykład:java.lang.IllegalArgumentException: Mismatched argument count to recur, expected: 1 args, got: 2, compiling:
(string->integer s 10)
)?Możesz także zniszczyć
rest
argumenty jako mapę od Clojure 1.2 [ ref ]. Pozwala to nazwać i podać wartości domyślne dla argumentów funkcji:Teraz możesz zadzwonić
lub
Możesz to zobaczyć w akcji tutaj: https://github.com/Raynes/clavatar/blob/master/src/clavatar/core.clj (na przykład)
źródło
To rozwiązanie jest tym bliższe duchowi oryginalnego rozwiązania , ale jest minimalnie czystsze
Podobny wzór , które mogą być przydatne zastosowania
or
w połączeniu zlet
Chociaż w tym przypadku jest bardziej rozwlekły, może być przydatny, jeśli chcesz, aby wartości domyślne zależały od innych wartości wejściowych . Na przykład rozważmy następującą funkcję:
To podejście można łatwo rozszerzyć tak, aby pracowało z nazwanymi argumentami (jak w rozwiązaniu M. Gilliara):
Lub używając jeszcze więcej fuzji:
źródło
or
or
różni się od,:or
ponieważor
nie zna różnicynil
ifalse
.Jest jeszcze jedno podejście, które warto rozważyć: funkcje częściowe . Są to prawdopodobnie bardziej „funkcjonalne” i bardziej elastyczne sposoby określania wartości domyślnych funkcji.
Zacznij od utworzenia (jeśli to konieczne) funkcji, której parametr (y) chcesz podać jako domyślne jako parametry wiodące:
Dzieje się tak, ponieważ wersja Clojure
partial
umożliwia podanie wartości „domyślnych” tylko w kolejności, w jakiej pojawiają się one w definicji funkcji. Po uporządkowaniu parametrów zgodnie z życzeniem można utworzyć „domyślną” wersję funkcji za pomocąpartial
funkcji:Aby ta funkcja była wywoływana wiele razy, możesz umieścić ją w zmiennej za pomocą
def
:Możesz także utworzyć „lokalną wartość domyślną” za pomocą
let
:Podejście do funkcji częściowych ma jedną kluczową przewagę nad innymi: odbiorca funkcji nadal może zdecydować, jaka będzie wartość domyślna, a nie producent funkcji, bez konieczności modyfikowania definicji funkcji . Jest to zilustrowane na przykładzie, w
hex
którym zdecydowałem, że domyślna funkcjadecimal
nie jest tym, czego chcę.Kolejną zaletą tego podejścia jest możliwość przypisania funkcji domyślnej innej nazwy (dziesiętnej, szesnastkowej itp.), Która może być bardziej opisowa i / lub mieć inny zakres (zmienna, lokalna). W razie potrzeby funkcję częściową można również łączyć z niektórymi z powyższych podejść:
(Zauważ, że różni się to nieco od odpowiedzi Briana, ponieważ kolejność parametrów została odwrócona z powodów podanych na górze tej odpowiedzi)
źródło
Możesz również zajrzeć do
(fnil)
https://clojuredocs.org/clojure.core/fnilźródło