2011-09-26 5 views
15

다음 Clojure 프로그램이 NullPointerException을 발생시키는 이유는 무엇입니까? 지점의 내부 {:status 200, :body "Hello World"} -Clojure에서 if 문 다음에 두 개의 명령을 연속적으로 실행하십시오.

user=> (defn x [] 
     "Do two things if the expression is true." 
     (if true ((println "first expr") (println "second expr")) false)) 

user=> (x) 
first expr 
java.lang.NullPointerException (NO_SOURCE_FILE:0) 
second expr 

이것은 내가지도를 반환하기 전에 어쩌면 세 개의 문합니다 (DB에서 풀 값)을 실행하려는 내 실제 사용 케이스의 단순화 된 버전입니다.

+0

본문에 여러 표현을 사용하여 doseq를 실행할 때 클로저에 [Nullpointer]가 중복 될 수 있음 (http://stackoverflow.com/questions/1530555/nullpointer-in-clojure-when-running-doseq-with-multiple-expressions) - 인 - 시체) – amalloy

답변

31

첫 번째 println의 결과를 두 번째 println 함수를 호출하는 함수로 처리하려고합니다.

do이 필요합니다. (반응식에서 시작 CL에 progn)

(defn x [] 
    "Do two things if the expression is true." 
    (if true (do (println "first expr") (println "second expr")) false)) 

(x) 
do

특별한 형태의 순서로 각 인수를 실행하고, 마지막 하나의 결과를 반환한다. nil가 다른 경우의 반환 값으로 괜찮

+0

예, 일반적으로. 몇 가지 형태가 그것을 암시 할 수 있습니다 (Scheme'cond'는 그것을 의미합니다. 예를 들어, Clojure의 버전은 인수가 목록에 없기 때문에 그렇게하지 않습니다). '((foo ...) (bar ...))'_generally_는 foo의 결과를 받아 함수의 나머지 인수를 호출하는 것을 의미합니다. – Random832

+0

이렇게하면'do' 명령문이 순차적으로 실행됩니다. (부작용이 있다고 가정 할 것인가?) –

+0

'do'는 실제로 그 문장을 순차적으로 실행합니다. – Hugh

10

경우, 암시 적 do 블록이 when 사용을 고려 : 그것은 당신의 특별한 경우에 중요하지 않는 것이

(defn x [] 
    "Do two things if the expression is true." 
    (when true 
    (println "first expr") 
    (println "second expr"))) 
7

,하지만 (do ...)을 사이의 차이를 알 수 있습니까 자체 클래스 로더에서 각 양식을로드하는 빈 양식과 단일 클래스 로더에서 전체 양식을 평가하는 (let [] ...) 양식이 있습니다.

+2

자체 클래스 로더에서 각 폼을로드하는 것과 그렇지 않은 경우의 실제적인 차이점은 무엇입니까? 어쩌면 클래스 로더의 의미를 이해하지 못할 수도 있습니다. –

+2

예를 들어, 사용자 정의 deftype 및 다중 클래스를 정의하는 매크로를 작성하고 있습니다. 최적화로서 동일한 클래스 로더를 사용하여보다 적은 클래스 로더 인스턴스를 생성하고자합니다. – bmillare