common-lisp
통제 구조
수색…
조건부 구문
Common Lisp에서 if
는 가장 단순한 조건문입니다. 이 형태를 갖는다 (if test then [else])
하고 평가 then
만약 test
참이고, else
그렇지. else 부분은 생략 될 수 있습니다.
(if (> 3 2)
"Three is bigger!"
"Two is bigger!")
;;=> "Three is bigger!"
Common Lisp에서 if
와 다른 많은 프로그래밍 언어에서 if
중요한 차이점 중 하나는 CL의 if
가 statement가 아니라 expression이라는 것입니다. 이와 같이, if
형태의 변수에 할당 인자리스트 등으로 사용할 수있는 값을 반환 :
;; Use a different format string depending on the type of x
(format t (if (numberp x)
"~x~%"
"~a~%")
x)
Common Lisp의 if
는 C # 및 다른 "중괄호"언어의 삼항 연산자 와 동등한 것으로 간주 if
수 있습니다.
예를 들어, 다음 C # 표현식은 다음과 같습니다.
year == 1990 ? "Hammertime" : "Not Hammertime"
그 year
가 정수를 가지고 있다고 가정하고 다음 Common Lisp 코드와 동일하다 :
(if (eql year 1990) "Hammertime" "Not Hammertime")
cond
는 또 다른 조건부 구조입니다. if
문 체인과 다소 유사하며 다음과 같은 형식을 취합니다.
(cond (test-1 consequent-1-1 consequent-2-1 ...)
(test-2)
(test-3 consequent-3-1 ...)
... )
보다 정확하게 말하면, cond
에는 0 개 이상의 절이 있고 각 절에는 0 개 이상의 결과가 나오는 테스트가 하나씩 있습니다. 전체 cond
구문은 테스트가 nil
이 아닌 첫 번째 절을 선택하고 그 결과를 순서대로 평가합니다. 결과의 마지막 형식 값을 반환합니다.
(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!"
다른 절은 평가하지 않는 경우 평가하는 기본 절 제공하기 위해 t
, 당신은 사용 기본적으로 사실이다 조항 추가 할 수 있습니다 t
. 이것은 개념상 SQL의 CASE...ELSE
와 매우 유사하지만 작업을 수행하기 위해 키워드가 아닌 실제 리터럴 부울을 사용합니다.
(cond
((= n 1) "N equals 1")
(t "N doesn't equal 1")
)
if
구문은 cond
구문으로 작성할 수 있습니다. (if test then else)
와 (cond (test then) (t else))
는 동일합니다.
당신은 하나의 절을해야하는 경우, 사용 when
또는 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 루프
Common Lisp의 대부분의 루핑 및 조건부 구문은 실제로는 기본 구문을 숨기는 매크로 입니다. 예를 들어 dotimes
와 dolist
는 do
매크로를 기반으로합니다. do
대한 양식 do
다음과 같습니다.
(do (varlist)
(endlist)
&body)
-
varlist
는 루프에 정의 된 변수, 초기 값 및 각 반복 후에 변수가 어떻게 변하는 지 구성됩니다. '변경'부분은 루프의 끝에서 평가됩니다. -
endlist
에는 루프의 끝에서 반환되는 끝 조건과 값이 포함됩니다. 종료 조건은 루프 시작 부분에서 평가됩니다.
0에서 시작하여 10까지 올라갑니다.
;;same as (dotimes (i 10))
(do (( i (+ 1 i))
((< i 10) i)
(print i))
목록을 통해 이동하는 방법은 다음과 같습니다.
;;same as (dolist (item given-list)
(do ((item (car given-list))
(temp list (cdr temp))
(print item))
varlist
부분은 let
문과 유사합니다. 둘 이상의 변수를 바인딩 할 수 있으며 루프 내에 만 존재합니다. 선언 된 각 변수는 자체 괄호 집합 안에 있습니다. 여기에 1과 2가 몇 개 있는지를 계산하는 방법이 있습니다.
(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)
while 루프 매크로가 구현되지 않은 경우 :
(do ()
(t)
(when task-done
(break)))
가장 일반적인 응용 프로그램의 경우보다 구체적인 dotimes
및 doloop
매크로가 훨씬 더 간결합니다.