2017-11-01 5 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 またはローカルバインディングを機能するように割り当てることはできません。 Clojureでは、Javaフィールド、Vars、Refs、Agentsのみが変更可能です。詳細については、http://clojure.org/special_formsを参照してください。

0

あなたはちょうどあなたがJavaの変数を使用する​​任意の場所を使用して、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))) 
結果と

: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のドキュメントを調べなければなりませんでした(私は" clojure forv "をgoogled)。ライブラリのコードは、SOの質問と回答でエイリアス修飾されている必要があります(つまり、 't/forv')。 –

+0

あなたは大歓迎です:)可能であれば、他のユーザーがこの回答を見つけやすいように、回答(緑色のチェックマーク)を「受け入れる」と「+1」の投票(上向き矢印/三角形)を付けてください。ありがとう。 –

関連する問題