2017-11-01 6 views
0

안녕하세요. 내 clojure 프로그램을 실행하는 동안 런타임 오류 메시지가 표시됩니다. java.lang.IllegalArgumentException가 :에 의한clojure - 함수가 변수를 변경할 수 없습니다.

비 가변에 할당 할 수 없습니다 : X

이 코드의 문제를 해결할 수 있도록 제가이 변경 가능한 변수에 대해 이해하고 있지 않다 무엇인지 알려 주시기 바랍니다. 미리 감사드립니다.

(defn gcd [a b] 
    (if (zero? b) 
    a 
    (recur b (mod a b)) 
) 
) 

(defn euler_phi [n] 
    (let [x 0] 
    (loop [idx_i 1] 
     (when (= 1 (gcd idx_i n)) 
     (set! x (inc x)) 
     (print " * ") 
    ) 
     (when (< idx_i n) 
     (recur (inc idx_i)) 
    ) 
    ) 
    x 
) 
) 
+1

오류 메시지가 정확합니다 :'x'가 원자 또는 다른 참조 유형이 아니라면'set! '할 수 없습니다. –

답변

2

set! Doc 당신은 또는 로컬 바인딩 PARAMS 기능을 할당 할 수 없습니다. Java 필드, Vars, 참조 및 에이전트 만 Clojure에서 변경할 수 있습니다. 자세한 내용은 http://clojure.org/special_forms을 참조하십시오.

0

당신은 단지 atom 당신이 자바 변수를 사용하는 것이 어떤 장소 사용, Clojure의에서 필수적 스타일 코드를 작성하려면 : 여기

n: 0  *  result= 1 
n: 1  *  result= 1 
n: 2  *  result= 1 
n: 3  * *  result= 2 
n: 4  * *  result= 2 
n: 5  * * * *  result= 4 
n: 6  * *  result= 2 
n: 7  * * * * * *  result= 6 
n: 8  * * * *  result= 4 
n: 9  * * * * * *  result= 6 
n: 10  * * * *  result= 4 
n: 11  * * * * * * * * * *  result= 10 
n: 12  * * * *  result= 4 
n: 13  * * * * * * * * * * * *  result= 12 
n: 14  * * * * * *  result= 6 
n: 15  * * * * * * * *  result= 8 
n: 16  * * * * * * * *  result= 8 
n: 17  * * * * * * * * * * * * * * * *  result= 16 
n: 18  * * * * * *  result= 6 
n: 19  * * * * * * * * * * * * * * * * * *  result= 18 
n: 20  * * * * * * * *  result= 8 
n: 21  * * * * * * * * * * * *  result= 12 
n: 22  * * * * * * * * * *  result= 10 
n: 23  * * * * * * * * * * * * * * * * * * * * * *  result= 22 
n: 24  * * * * * * * *  result= 8 
n: 25  * * * * * * * * * * * * * * * * * * * *  result= 20 
n: 26  * * * * * * * * * * * *  result= 12 
n: 27  * * * * * * * * * * * * * * * * * *  result= 18 
n: 28  * * * * * * * * * * * *  result= 12 
n: 29  * * * * * * * * * * * * * * * * * * * * * * * * * * * *  result= 28 

: 결과와

(ns tst.demo.core 
    (:use demo.core)) 

(defn gcd [a b] 
    (if (zero? b) 
    a 
    (recur b (mod a b)))) 

(defn euler-phi [n] 
    (let [x (atom 0)] 
    (loop [idx 1] 
     (when (= 1 (gcd idx n)) 
     (swap! x inc) 
     (print " * ")) 
     (when (< idx n) 
     (recur (inc idx)))) 
    @x)) 

(dotimes [n 30] 
    (print "n:" n " ") 
    (let [result (euler-phi n)] 
    (println " result=" result))) 

을 코드의보다 기능적인 버전입니다 :

(ns tst.demo.core 
    (:use demo.core tupelo.test) 
    (:require [tupelo.core :as t])) 
(t/refer-tupelo) 

(defn gcd [a b] 
    (if (zero? b) 
    a 
    (recur b (mod a b)))) 

(defn euler-phi [n] 
    (apply + 
    (t/forv [idx (t/thru 1 n)] 
     (if (= 1 (gcd idx n)) 
     1 
     0)))) 

(dotimes [n 30] 
    (println "n:" n " result=" (euler-phi n))) 
결과 16,

: N = 0의 결과가 다른 것을

n: 0  result= 0 
n: 1  result= 1 
n: 2  result= 1 
n: 3  result= 2 
n: 4  result= 2 
n: 5  result= 4 
n: 6  result= 2 
n: 7  result= 6 
n: 8  result= 4 
n: 9  result= 6 
n: 10  result= 4 
n: 11  result= 10 
n: 12  result= 4 
n: 13  result= 12 
n: 14  result= 6 
n: 15  result= 8 
n: 16  result= 8 
n: 17  result= 16 
n: 18  result= 6 
n: 19  result= 18 
n: 20  result= 8 
n: 21  result= 12 
n: 22  result= 10 
n: 23  result= 22 
n: 24  result= 8 
n: 25  result= 20 
n: 26  result= 12 
n: 27  result= 18 
n: 28  result= 12 
n: 29  result= 28 

주 ..... 나는 그것을 디버깅하려고하지 않았다.

+3

'forv'가 Clojure (내가 "clojure forv"라고 썼습니다.)의 일부인지 확인하기 위해 Clojure 문서를 조사해야했습니다. 라이브러리의 코드는 SO 질문 및 답변에서 별칭을 사용해야합니다 (예 :'t/forv'). –

+0

당신은 환영합니다 :) 추신 가능한 경우 다른 사용자가이 대답을 더 쉽게 찾을 수 있도록 답변 (녹색 확인 표시)을 "수락"하고 "+1"투표 (위쪽 화살표/삼각형)를주십시오. 감사. –