Szukaj…


Konstrukcje warunkowe

W Common Lisp, if jest najprostszą konstrukcją warunkową. Ma on formę (if test then [else]) i ocenia się then , jeśli test jest prawdziwe, else inaczej. Inną część można pominąć.

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

Jedna bardzo ważna różnica między if w Common Lisp i if w wielu innych językach programowania jest to, że CL if jest wyrazem, a nie stwierdzenie. Jako taki, if formularze zwracają wartości, które można przypisać do zmiennych, używanych na listach argumentów itp .:

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

Typowe Lisp, if można je uznać za równoważne z operatorem potrójnym?: W języku C # i innych językach nawiasów klamrowych.

Na przykład następujące wyrażenie C #:

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

Odpowiada poniższemu wspólnemu kodowi Lisp, przy założeniu, że year ma liczbę całkowitą:

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

cond to kolejna konstrukcja warunkowa. Jest nieco podobny do łańcucha instrukcji if i ma postać:

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

Dokładniej, cond ma zero lub więcej klauzul , a każda klauzula ma jeden test, po którym następuje zero lub więcej następstw. Cały konstrukt cond wybiera pierwszą klauzulę, której test nie jest nil i ocenia kolejno następstwa. Zwraca wartość ostatniej formy w wynikach.

(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!"

Aby zapewnić domyślną klauzulę do oceny, czy żadna inna klauzula nie ocenia na t , możesz dodać klauzulę, która jest domyślnie prawdziwa, używając t . Jest to bardzo podobne w koncepcji do instrukcji CASE...ELSE SQL, ale do wykonania zadania używa dosłownie logicznej wartości prawda, a nie słowa kluczowego.

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

Konstrukt if można zapisać jako konstrukt cond . (if test then else) i (cond (test then) (t else)) są równoważne.

Jeśli potrzebujesz tylko jednej klauzuli, użyj when lub o 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

Pętla do

Większość zapętlonych i warunkowych konstrukcji w Common Lisp to tak naprawdę makra, które ukrywają bardziej podstawowe konstrukcje. Na przykład, dotimes i dolist są zbudowane na do makro. Formularz do wygląda następująco:

(do (varlist)
    (endlist)
   &body)
  • varlist składa się ze zmiennych zdefiniowanych w pętli, ich wartości początkowych i tego, jak zmieniają się po każdej iteracji. Część „zmiany” jest oceniana na końcu pętli.
  • endlist zawiera warunki końcowe i wartości zwracane na końcu pętli. Stan końcowy jest oceniany na początku pętli.

Oto ten, który zaczyna się od 0 i idzie w górę do (bez) 10.

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

A oto jedna, która porusza się po liście:

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

Część varlist jest podobna do tej w instrukcji let . Możesz powiązać więcej niż jedną zmienną, a one istnieją tylko w pętli. Każda deklarowana zmienna ma własny zestaw nawiasów. Oto jeden, który liczy, ile 1 i 2 jest na liście.

(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)

A jeśli makro pętli while nie zostało zaimplementowane:

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

W przypadku najczęstszych zastosowań bardziej szczegółowe makra dotimes i doloop są znacznie bardziej zwięzłe.



Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow