Sök…


Villkorliga konstruktioner

I Common Lisp, if är den enklaste villkorade konstruktionen. Den har formen (if test then [else]) och utvärderas till then om test är sant och else sätt. Den andra delen kan utelämnas.

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

En mycket viktig skillnad mellan if i Common Lisp och if i många andra programmeringsspråk är att CL: s if är ett uttryck, inte ett uttalande. Som sådan, if formulär returnerar värden, som kan tilldelas variabler, som används i argumentlistor, etc:

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

Vanliga Lisp if kan betraktas som likvärdiga med den ternära operatören ?: på C # och andra "lockiga stag" -språk.

Till exempel följande C # -uttryck:

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

Är likvärdigt med följande Common Lisp-kod, förutsatt att year har ett heltal:

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

cond är en annan villkorad konstruktion. Det liknar en kedja av if uttalanden och har formen:

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

Mer exakt har cond noll eller fler klausuler , och varje klausul har ett test följt av noll eller fler följder. Hela cond konstruktionen väljer den första klausulen vars test inte utvärderar till nil och utvärderar dess följder i ordning. Det returnerar värdet på den sista formen i följdarna.

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

Om du vill tillhandahålla en standardklausul för att utvärdera om ingen annan klausul utvärderas till t kan du lägga till en klausul som är sann som standard med t . Detta är mycket lika i koncept som SQL: s CASE...ELSE , men det använder en bokstavlig booleska sann snarare än ett nyckelord för att utföra uppgiften.

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

En if konstruktion kan skrivas som en cond konstruktion. (if test then else) och (cond (test then) (t else)) är likvärdiga.

Om du bara behöver en klausul, använd when eller om 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

Do loopen

De flesta looping och villkorade konstruktioner i Common Lisp är faktiskt makroer som döljer bort mer grundläggande konstruktioner. Till exempel dotimes och dolistdo makroen. Formuläret för do ser ut så här:

(do (varlist)
    (endlist)
   &body)
  • varlist består av variablerna definierade i loopen, deras initiala värden och hur de ändras efter varje iteration. "Ändra" -delen utvärderas i slutet av slingan.
  • endlist innehåller endlist och värden som returneras i slutet av slingan. Slutvillkoret utvärderas i början av slingan.

Här är en som börjar på 0 och går upp till (inte inklusive) 10.

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

Och här är en som går igenom en lista:

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

varlist är lik den i ett let uttalande. Du kan binda mer än en variabel, och de finns bara i slingan. Varje variabel som deklareras finns i sin egen uppsättning parentes. Här är en som räknar hur många 1 och 2 som finns i en 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)

Och om en makroslinga inte har implementerats:

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

För de vanligaste tillämpningarna är de mer specifika dotimes och doloop mycket mer kortfattade.



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow