Ich komme mit:
(defn string-> integer [str & [base]] (Integer / parseInt str (if (nil? Base) 10 base))) (string-> integer "10") (string-> integer "FF" 16)
Aber es muss ein besserer Weg sein, dies zu tun.
Ich komme mit:
(defn string-> integer [str & [base]] (Integer / parseInt str (if (nil? Base) 10 base))) (string-> integer "10") (string-> integer "FF" 16)
Aber es muss ein besserer Weg sein, dies zu tun.
Eine Funktion kann mehrere Signaturen haben, wenn sich die Signaturen in ihrer Arität unterscheiden. Damit können Sie Standardwerte angeben.
(defn string->integer
([s] (string->integer s 10))
([s base] (Integer/parseInt s base)))
Beachten Sie, dass unter der Annahme , false
und nil
beide nicht-Werte betrachtet, (if (nil? base) 10 base)
könnte verkürzt werden (if base base 10)
, oder weiter zu (or base 10)
.
(recur s 10)
,recur
anstatt den Funktionsnamen zu wiederholenstring->integer
. Das würde es in Zukunft einfacher machen, die Funktion umzubenennen. Kennt jemand einen Grund,recur
in diesen Situationen nicht zu verwenden ?recur
nur mit derselben Arität gearbeitet. Wenn Sie oben versucht haben, zum Beispiel:java.lang.IllegalArgumentException: Mismatched argument count to recur, expected: 1 args, got: 2, compiling:
(string->integer s 10)
)?Sie können
rest
Argumente seit Clojure 1.2 [ ref ] auch als Map zerstören . Auf diese Weise können Sie Funktionsargumente benennen und Standardeinstellungen angeben:Jetzt können Sie anrufen
oder
Sie können dies hier in Aktion sehen: https://github.com/Raynes/clavatar/blob/master/src/clavatar/core.clj (zum Beispiel)
quelle
Diese Lösung ist dem Geist der ursprünglichen Lösung näher , aber geringfügig sauberer
Ein ähnliches Muster, das nützlich sein kann,
or
kombiniert mitlet
In diesem Fall ist dies zwar ausführlicher, es kann jedoch hilfreich sein, wenn die Standardeinstellungen von anderen Eingabewerten abhängen sollen . Betrachten Sie beispielsweise die folgende Funktion:
Dieser Ansatz kann leicht erweitert werden, um auch mit benannten Argumenten zu arbeiten (wie in der Lösung von M. Gilliar):
Oder noch mehr Fusion:
quelle
or
or
ist anders als:or
daor
kennt den Unterschied vonnil
und nichtfalse
.Es gibt noch einen anderen Ansatz, den Sie in Betracht ziehen sollten: Teilfunktionen . Dies ist wohl eine "funktionalere" und flexiblere Möglichkeit, Standardwerte für Funktionen anzugeben.
Erstellen Sie zunächst (falls erforderlich) eine Funktion mit den Parametern, die Sie als Standardparameter als Hauptparameter bereitstellen möchten:
Dies geschieht, weil Sie mit Clojures Version von
partial
die "Standard" -Werte nur in der Reihenfolge angeben können, in der sie in der Funktionsdefinition angezeigt werden. Nachdem die Parameter wie gewünscht bestellt wurden, können Sie mit der folgendenpartial
Funktion eine "Standard" -Version der Funktion erstellen :Um diese Funktion mehrmals aufrufbar zu machen, können Sie sie in eine Variable einfügen, indem Sie Folgendes verwenden
def
:Sie können auch einen "lokalen Standard" erstellen, indem Sie
let
:Der Teilfunktionsansatz hat einen entscheidenden Vorteil gegenüber den anderen: Der Benutzer der Funktion kann weiterhin entscheiden, wie hoch der Standardwert sein soll, und nicht der Hersteller der Funktion, ohne die Funktionsdefinition ändern zu müssen . Dies wird in dem Beispiel veranschaulicht, in dem
hex
ich entschieden habe, dass die Standardfunktiondecimal
nicht das ist, was ich will.Ein weiterer Vorteil dieses Ansatzes besteht darin, dass Sie der Standardfunktion einen anderen Namen (dezimal, hexadezimal usw.) zuweisen können, der möglicherweise aussagekräftiger ist und / oder einen anderen Bereich (var, local). Falls gewünscht, kann die Teilfunktion auch mit einigen der oben genannten Ansätze gemischt werden:
(Beachten Sie, dass dies geringfügig von Brians Antwort abweicht, da die Reihenfolge der Parameter aus den oben in dieser Antwort angegebenen Gründen umgekehrt wurde.)
quelle
Sie können sich auch https://clojuredocs.org/clojure.core/fnil ansehen
(fnil)
quelle