在Clojure中使用Java的Scanner

时间:2014-03-10 22:20:54

标签: java clojure

我正在尝试使用Java Scanner从clojure的读取线中分离输入。我认为这只是一个基本错误,我发现Clojure并不是一个新手。代码如下:

(defn select-option
  []

(def option (read-line))
(println "test")
(def s (Scanner. option))
(println "test")
(def opt (.next s))
(println "test")

(case opt ("s"  (println "case test")
                (def lastn (.next s))
                (def firstn (.next s))
                (new-student lastn firstn))))

但输入“s firstName lastName”

后,我得到以下输出
test
test
test
ClassCastException java.lang.String cannot be cast to clojure.lang.IFn  GradingSystem1.core/select-option (NO_SOURCE_FILE:12)

我认为我在使用java代码时出错,但是非常感谢任何帮助,谢谢!

1 个答案:

答案 0 :(得分:1)

("s" ..)中有一组额外的parens被解释为对函数" s"的函数调用。这是因为" s"不是一个功能。使用let定义函数内部的名称也更好,因为这里使用def对于并发操作是不安全的。

一个翻译可能看起来像这样:

(defn select-option []                       
  (let [option (read-line)                   
        _ (println "test")                   
        s (Scanner. option)                  
        _ (println "test")                   
        opt (.next s)                        
        _ (println "test")]                  
    (case opt                                
       "s"  (println "case test")             
      (let [lastn (.next s)                  
            firstn (.next s)]                
        (new-student lastn firstn)))))  

Def始终定义顶级var,因此如果您在函数中使用它,则该函数的所有实例将共享相同的值并相互干扰。在Clojure中,用于定义词法范围的构造是let表达式。在上面的例子中,我使用名称_来表示我不会做任何事情的值(打印结果),这只是一个惯例,虽然它表明它可以使用相同的在let表达式中多次命名(以后可以使用以前的值,如果需要)。