2016-07-16 6 views
3

Können Sie eine Funktion mit und optionalen Parameter als erste und einzige Parameter haben?Kann ersten Parameter nicht als optional haben

so

(defn foo [& bar] (if (= bar) 1 2))

+2

'(= x)' in Clojure ist immer "wahr", egal was 'x' ist, solange' x' die Ausführung des Formulars nicht durch Auslösen einer Ausnahme stört – noisesmith

Antwort

10

Was & bar bei Funktionsdefinition bedeutet, dass der ganze Rest der Argumente werden in eine Liste gesetzt werden. Es gibt keine Garantien hinsichtlich der Größe der Liste, daher könnte sie leer sein, mit einem oder mehreren Elementen.

Ein besserer Ansatz zu einem und nur optionales Argumente ist es null oder eins Argument zu haben, akzeptieren:

(defn foo 
    ([] (foo 12)) 
    ([bar] (if (= bar 12) 1 2))) 

In diesem Beispiel, wenn Sie die erste Funktionsdefinition, mit Null arity nennen, wird es rufen Sie einfach die zweite 1-arity Funktionsdefinition mit einem Standardwert von 12.

0

Diese Arbeit wird:

(defn foo [& bar] 
    (if (seq bar) 1 2)) 

seq Verwendung ist so, wie Sie ein soll "nicht leer" kodieren. Nicht zu verwechseln mit seq?, was etwas ganz anderes bedeutet, die in der Tat true hier zurückgeben wird.

Der wichtige Punkt ist, dass bar eine Liste innerhalb des Funktionskörpers wird. Wenn Sie diese Liste wieder auf das bringen wollen, was sie beim Aufruf der Funktion war, dann verwenden Sie apply, oder dekonstruieren Sie die Liste in der Funktion selbst, wie in den Kommentaren unten erklärt ...

+5

Ein übliches Muster ist '[& [bar]]', das den ersten zerstört Parameter und macht es optional. – ClojureMostly

+0

@ClojureMostly Aber das führt dazu, dass zusätzliche Argumente stillschweigend ignoriert werden, was zu kleinen Fehlern wie [this] (https://github.com/magomimmo/modern-cljs/issues/373) führen kann. –

Verwandte Themen