Suche…


Bedingte Konstrukte

In Common Lisp ist if das einfachste bedingte Konstrukt. Sie hat die Form (if test then [else]) der then test else (if test then [else]) und wird ausgewertet then , wenn test wahr ist und else nichts anderes. Der else Teil kann weggelassen werden.

(if (> 3 2)
    "Three is bigger!"
    "Two is bigger!")
;;=> "Three is bigger!"

Ein sehr wichtiger Unterschied zwischen if in Common Lisp und if in vielen anderen Programmiersprachen ist, dass CLs if ein Ausdruck und keine Aussage ist. if Formulare Werte zurückgeben, die Variablen zugewiesen werden können, werden sie in Argumentlisten verwendet.

;; Use a different format string depending on the type of x
(format t (if (numberp x)
              "~x~%"
              "~a~%")
           x)

Common Lisp's if kann als äquivalent zu dem ternären Operator angesehen werden: in C # und anderen "geschweiften Klammern".

Beispielsweise der folgende C # -Ausdruck:

year == 1990 ? "Hammertime" : "Not Hammertime"

Entspricht dem folgenden Common Lisp-Code, sofern das year eine ganze Zahl enthält:

(if (eql year 1990) "Hammertime" "Not Hammertime")

cond ist ein anderes bedingtes Konstrukt. Es ähnelt einer Kette von if Anweisungen und hat die Form:

(cond (test-1 consequent-1-1 consequent-2-1 ...)
      (test-2)
      (test-3 consequent-3-1 ...)
      ... )

Genauer gesagt, enthält cond null oder mehr Klauseln , und jede Klausel enthält einen Test, gefolgt von null oder mehr Konsequenzen. Das gesamte cond Konstrukt wählt die erste Klausel aus, deren Test nicht nil ergibt, und wertet die Folge davon aus. Es gibt den Wert des letzten Formulars in den Folgen zurück.

(cond ((> 3 4) "Three is bigger than four!")
      ((> 3 3) "Three is bigger than three!")
      ((> 3 2) "Three is bigger than two!")
      ((> 3 1) "Three is bigger than one!"))
;;=> "Three is bigger than two!"

Um eine Standardklausel zu bewerten , wenn keine andere Klausel auswertet t , können Sie eine Klausel hinzufügen, die standardmäßig mit zutrifft t . Dies ist in seinem Konzept dem von CASE...ELSE sehr ähnlich, aber es verwendet eine wörtliche Boolesche Wahrheit anstelle eines Schlüsselworts, um die Aufgabe auszuführen.

(cond
    ((= n 1) "N equals 1")
    (t "N doesn't equal 1")
)

Ein if Konstrukt kann als cond Konstrukt geschrieben werden. (if test then else) und (cond (test then) (t else)) sind gleichwertig.

Wenn Sie nur eine Klausel benötigen, verwenden Sie when oder unless :

(when (> 3 4)
  "Three is bigger than four.")
;;=> NIL

(when (< 2 5)
  "Two is smaller than five.")
;;=> "Two is smaller than five."

(unless (> 3 4)
  "Three is bigger than four.")
;;=> "Three is bigger than four."

(unless (< 2 5)
  "Two is smaller than five.")
;;=> NIL

Die do-Schleife

Die meisten schleifen- und bedingten Konstrukte in Common Lisp sind eigentlich Makros , die einfachere Konstrukte ausblenden. dotimes und dolist basieren beispielsweise auf dem do Makro. Das Formular für do sieht folgendermaßen aus:

(do (varlist)
    (endlist)
   &body)
  • varlist besteht aus den in der Schleife definierten Variablen, ihren Anfangswerten und wie sie sich nach jeder Iteration ändern. Der Änderungsabschnitt wird am Ende der Schleife ausgewertet.
  • endlist enthält die endlist und die am Ende der Schleife zurückgegebenen Werte. Die Endebedingung wird zu Beginn der Schleife ausgewertet.

Hier beginnt man bei 0 und geht bis 10 (nicht einschließlich).

;;same as (dotimes (i 10)) 
(do (( i (+ 1 i))
    ((< i 10) i)
   (print i))

Und hier ist eine, die sich durch eine Liste bewegt:

;;same as (dolist (item given-list)
(do ((item (car given-list))
     (temp list (cdr temp))
   (print item))

Der varlist Teil ist dem einer let Anweisung ähnlich. Sie können mehrere Variablen binden, die nur in der Schleife vorhanden sind. Jede deklarierte Variable befindet sich in einer eigenen Klammer. Hier ist eine, die zählt, wie viele Einsen und Zweien in einer Liste enthalten sind.

(let ((vars (list 1 2 3 2 2 1)))
  (do ((ones 0)
       (twos 0)
       (temp vars (cdr temp)))
      ((not temp) (list ones twos))
    (when (= (car temp) 1)
      (setf ones (+ 1 ones)))
    (when (= (car temp) 2)
      (setf twos (+ 1 twos)))))
-> (2 3)

Und wenn ein while-Loop-Makro nicht implementiert wurde:

(do ()
    (t)
  (when task-done
    (break)))

Für die häufigsten Anwendungen sind die spezifischeren dotimes und doloop Makros viel prägnanter.



Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow