Ricerca…


Costrutti condizionali

In Common Lisp, if è il costrutto condizionale più semplice. Ha il modulo (if test then [else]) e viene valutato per then se test è vero e else altrimenti. La parte else può essere omessa.

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

Una differenza molto importante tra if in Common Lisp e if in molti altri linguaggi di programmazione è che CL if è un'espressione, non un'istruzione. Di conseguenza, if moduli restituiscono valori, che possono essere assegnati a variabili, utilizzati negli elenchi di argomenti, ecc.

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

Common Lisp's if può essere considerato equivalente all'operatore ternario?: In C # e in altre lingue "parentesi graffe".

Ad esempio, la seguente espressione C #:

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

È equivalente al seguente codice Common Lisp, assumendo che year un intero:

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

cond è un altro costrutto condizionale. È in qualche modo simile a una catena di istruzioni if e ha la forma:

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

Più precisamente, cond ha zero o più clausole e ogni frase ha un test seguito da zero o più conseguenti. L'intero cond costrutto seleziona la prima clausola il cui test non valuta nil e valuta i suoi conseguenti nell'ordine. Restituisce il valore dell'ultima forma nei conseguenti.

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

Per fornire una clausola predefinita per valutare se nessun'altra clausola restituisce t , è possibile aggiungere una clausola vera per default usando t . Questo concetto è molto simile a quello di SQL CASE...ELSE , ma usa un vero valore booleano letterale piuttosto che una parola chiave per eseguire l'operazione.

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

Un costrutto if può essere scritto come costrutto cond . (if test then else) e (cond (test then) (t else)) sono equivalenti.

Se hai solo bisogno di una clausola, usa when 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

Il ciclo di do

La maggior parte dei loop e condizionali costrutti in Common Lisp sono in realtà le macro che nascondono via costrutti più basilari. Ad esempio, dotimes e dolist sono costruiti sul do macro. Il modulo per do aspetto:

(do (varlist)
    (endlist)
   &body)
  • varlist è composta dalle variabili definite nel ciclo, i loro valori iniziali, e come cambiano dopo ogni iterazione. La porzione 'cambiamento' viene valutata alla fine del ciclo.
  • endlist contiene le condizioni finali e valori restituiti al termine del ciclo. La condizione finale viene valutata all'inizio del ciclo.

Ecco uno che inizia a 0 e va fino a (ad esclusione di) 10.

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

Ed ecco uno che si muove attraverso una lista:

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

La porzione varlist è simile a quella in una dichiarazione let . È possibile associare più di una variabile e esistono solo all'interno del ciclo. Ogni variabile dichiarata è racchiusa tra parentesi. Ecco uno che conta quanti 1 e 2 sono in una lista.

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

E se una macro del ciclo while non è stata implementata:

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

Per le applicazioni più comuni, i più specifici dotimes e doloop macro sono molto più succinta.



Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow