1

足し算、引き算などを使った簡単な電卓を書こうとしています。

私の問題は、ユーザー入力を取得することです。数値の文字列をベクトルに変換するにはどうすればよいですか? また、プログラムを書くためのより良い方法は何ですか?

(ns scalc.core)

(defn add
  [numbers]
  (println (apply + numbers)))

(defn numchoose
  []
  (println "What numbers?: ")
  (let [numbers (read-line)] numbers))

(defn opchoose
  []
  (println "What operation would you like to do?: ")
  (let [operation (read-line)]

    (if (= operation "add")
      (do
        (println "You chose to add.")
        (let [numvect (numchoose)]
              (add [numvect]))))))


(defn -main
  [& args]

  (opchoose)
  (numchoose))

そして、これはエラーです:

 ~/clj/scalc 1/7 % lein trampoline run -m scalc.core
What operation would you like to do?: 
add
You chose to add.
What numbers?: 
5 7
Exception in thread "main" java.lang.ClassCastException: Cannot cast java.lang.String to java.lang.Number
        at java.lang.Class.cast(Class.java:3005)
        at clojure.core$cast.invoke(core.clj:318)
        at clojure.core$_PLUS_.invoke(core.clj:927)
        at clojure.lang.AFn.applyToHelper(AFn.java:161)
        at clojure.lang.RestFn.applyTo(RestFn.java:132)
        at clojure.core$apply.invoke(core.clj:601)
        at scalc.core$add.invoke(core.clj:5)
        at scalc.core$opchoose.invoke(core.clj:21)
        at scalc.core$_main.doInvoke(core.clj:27)
        at clojure.lang.RestFn.invoke(RestFn.java:397)
        at clojure.lang.Var.invoke(Var.java:411)
        at user$eval15.invoke(NO_SOURCE_FILE:1)
        at clojure.lang.Compiler.eval(Compiler.java:6511)
        at clojure.lang.Compiler.eval(Compiler.java:6501)
        at clojure.lang.Compiler.eval(Compiler.java:6477)
        at clojure.core$eval.invoke(core.clj:2797)
        at clojure.main$eval_opt.invoke(main.clj:297)
        at clojure.main$initialize.invoke(main.clj:316)
        at clojure.main$null_opt.invoke(main.clj:349)
        at clojure.main$main.doInvoke(main.clj:427)
        at clojure.lang.RestFn.invoke(RestFn.java:421)
        at clojure.lang.Var.invoke(Var.java:419)
        at clojure.lang.AFn.applyToHelper(AFn.java:163)
        at clojure.lang.Var.applyTo(Var.java:532)
        at clojure.main.main(main.java:37)

編集: 解決されたプログラムは次のようになります。

(ns scalc.core)

(defn add [numbers]
  (reduce + numbers))

(defn numchoose []
  (let [nums (re-seq #"\d+" (read-line))]
    (map #(Integer/parseInt %) nums)))

(defn delegate []
  (println "What operation would you like to do?: ")
  (let [operation (read-line)]

    (when (= operation "add")
      (println "You chose to add.")
      (println "What numbers? ")
      (add (numchoose)))))

(defn -main
  [& args]

  (delegate))
4

1 に答える 1

3

数値を取得するには、 re-seqを使用できます。

(re-seq #"\d+" "123 456 789") => ("123" "456" 789")

ただし、数値ではなく文字列しかありません。read-string を使用して数値を取得できます (read-string は便利ですが、すべての場合に安全というわけではありません。ここでは、これらの文字列に実際に数値のみが含まれていることを確認しているので問題ありません)。

(read-string "5") => 5

reduce :(apply + numbers)を使用する代わりに、 add 関数は実際には何も出力すべきではありません (可能な限り、関数関数を副作用関数から分離するようにしてください)(reduce + numbers)

これ(let [numbers (read-line)] numbers)は に等しい(read-line)です。物事を過度に複雑にしないでください。

それ以外の

(if (= operation "add")
      (do ... ))

あなたは書ける

(when (= operation "add")
     ...)

whenは、if で else ケースが必要ない場合に便利な単なるマクロです (条件の後のすべてを do でラップし、条件が false と評価されると nil と評価されます)。

于 2012-11-03T20:19:22.433 に答える