먼저 로컬 변수를 정의하려면 LET
or LET*
을 사용해야합니다.
(defun f (a b)
(let* ((c (* 4 a)) ; You need LET* instead of LET because
(d (* 2 (expt b 3))) ; RES depends on the previous variables.
(res (+ c d)))
(if (and (typep a 'integer) (typep b 'integer))
(list 'final 'value '= res)
'(your inputs are not numbers))))
실제 문제는 인수가 정수인지 확인하기 전에 계산을 수행하고 있다는 것입니다. IF
안에 계산을 이동해야합니다.
그런 목록을 반환하는 것은 이상합니다. 사용자를 위해 결과를 출력하려는 경우 메시지를 인쇄하고 실제 결과를 반환해야합니다.
(defun f (a b)
(if (and (integerp a) (integerp b))
(let ((result (+ (* 4 a)
(* 2 (expt b 3)))))
(format t "Final value = ~a~%" result)
result) ; Return RESULT or
(format t "Your inputs are not integers.~%"))) ; NIL from FORMAT.
대부분의 경우 인수가 올바른 유형이 아닌 경우 오류를 표시해야합니다. 계산을 수행하는 함수의 출력 결과는 대개 잘못된 아이디어입니다.
(defun f (a b)
(check-type a integer "an integer")
(check-type b integer "an integer")
(+ (* 4 a)
(* 2 (expt b 3))))
(defun main (a b)
(handler-case
(format t "Final value = ~a~%" (f a b))
;; CHECK-TYPE signals a TYPE-ERROR if the type is not correct.
(type-error() (warn "Your inputs are not integers."))))
(main 12 1)
; Final value = 50
;=> NIL
(main 12 'x)
; WARNING: Your inputs are not integers.
;=> NIL
Common Lisp 조건 시스템을 사용하면 다시 시작을 사용하여 오류를 수정할 수 있습니다. CHECK-TYPE
은 STORE-VALUE
이라는 이름의 다시 시작을 설정하며,이 곳에서 올바른 값을 제공 할 수 있습니다. 이 경우 아마도 이해가되지 않지만, 기본값으로 1
을 사용할 수 있습니다.
(defun main (a b)
(handler-bind ((type-error (lambda (e)
(store-value 1 e))))
(format t "Final value = ~a~%" (f a b))))
(main 12 1)
; Final value = 50
;=> NIL
(main 12 'x)
; Final value = 50
;=> NIL
조건/오류 처리기가 당신이 그들을 사용하고 대신 함수를 호출하기 전에 인수를 확인하고 싶지 않을 수도 성능에 중요한 기능을 위해, 그래서 약간의 오버 헤드를 추가 할 공지있다.
(declaim (ftype (function (integer integer) integer) f))
(defun f (a b)
(declare (optimize (speed 3) (safety 0) (debug 0)))
(+ (* 4 a)
(* 2 (expt b 3))))
(defun main (a b)
(if (and (integerp a)
(integerp b))
(format t "Final value = ~a~%" (f a b))
(warn "Your inputs are not integers.")))
초보자의 입장에서 볼 때 많은 도움이되었습니다. 귀중한 재료를 바탕으로 더욱 성장할 것입니다. 고맙습니다. –