我已经在Eclipse中运行了。我想在运行它时将参数传递给clojure。在下面,参数在REPL中可用,但在脚本本身中不可用。我需要做什么,以便在下面输入REPL中的arg1将返回第一个参数?
脚本:
(NS Test)
(def arg1 (nth *command-line-args* 0))
点击Eclipse“Run”...
Clojure 1.1.0
1:1 user=> #<Namespace test>
1:2 test=> arg1
nil
1:3 test=> *command-line-args*
("bird" "dog" "cat" "pig")
1:4 test=> (def arg2 (nth *command-line-args* 1))
#'test/arg2
1:5 test=> arg2
"dog"
1:6 test=>
答案 0 :(得分:3)
似乎可能在arg1
获取值之前定义了*command-line-args*
。 *command-line-args*
位于clojure.core
中,因此每个命名空间都应该能够看到它(除非您定义命名空间并明确指示它排除core
或排除该var)。我不知道Eclipse如何启动REPL或者如何/何时加载命名空间或用户代码,所以我不知道这个问题。
但是你可以将arg1
变成一个函数,然后它应该总是返回*command-line-args*
的当前值(因为它将在运行时被解析,而*command-line-args*
应该有一个调用函数时的值。)
(defn arg1 [] (nth *command-line-args* 0))
更好的是,如果(nth *command-line-args* 0)
真的很难打字(我认为不是真的那样),你可以写一个更好的功能:
(defn ARGV [n] (nth *command-line-args* n))
然后使用(ARGV 0)
,(ARGV 1)
等。请记住,向量本身就是其参数的函数,因此您可以直接轻松地执行(*command-line-args* n)
(一旦您确定{ {1}}不是*command-line-args*
;否则您将获得NullPointerException。)
在Clojure中,使用大量nil
来为顶级事物指定名称通常不是惯用的。如果你想在本地引用命令行参数并暂时给它们一个较短的名字,那就是def
:
let
同样,这种方式(defn foo []
(let [arg1 (nth *command-line-args* 0)]
...))
应该在运行时获得它的值(每当你调用arg1
时)它应该可以工作。