我正在通过我的第一个Clojure程序。我还有一件事就是让我的程序接受命令行参数。 args的数量可以变化(但需要至少为1),然后每个命令行arg需要作为参数提供给main
中的函数,一次一个。我一直在网上阅读,似乎clojure/tools.cli
是这样做的方式,(可能使用parse-opts
?)。但我无法理解我的生活。没有验证,真的需要发生 - 无论用户提供什么都是有效的。 (唯一需要检查的是至少提供了一个参数)。关于如何解决这个问题的任何建议?
我遇到的所有例子看起来都非常复杂,很容易过头。
我正在尝试做的一个简单示例是在用户提供任意数量的命令行参数之后,然后使用clojure在终端的新行中打印每个字符串。
我使用leiningen来运行我的程序。
答案 0 :(得分:2)
简单的方法是使用clojure.core/*command-line-args*
:
(doseq [arg *command-line-args*]
(println (str "Read an argument: " arg)))
答案 1 :(得分:2)
因为你的整个问题似乎归结为:
我正在尝试做的一个简单示例是在用户提供任意数量的命令行参数之后,然后让clojure在终端的新行中打印每个字符串。
我会回答的。这可以相当简洁地完成:
(defn -main [& args] ; & creates a list of var-args
(if-not (empty? args)
; Foreach arg, print the arg...
(doseq [arg args]
(println arg))
; Handle failure however here
(throw (Exception. "Must have at least one argument!"))))
注意,除非绝对想要在传递0个参数时彻底失败,否则可以跳过empty?
检查。如果doseq
为空,则args
将无法运行,因为没有任何要迭代的内容。
您还可以将整个doseq
替换为:
(mapv println args)
但这可能是滥用mapv
。
答案 2 :(得分:0)
可以做很多事情,解析和验证命令行参数就是其中之一。这是一个例子:
(ns cmdargs.core
(:require [clojure.spec.alpha :as spec]))
;; Specification of a single argument.
;; For example, replace `any?` by `number?`
;; if your program only accepts numeric args.
(spec/def ::arg any?)
(spec/def ::args (spec/+ ::arg))
(defn my-fun [& args]
(doseq [arg args]
(println "Got arg: " arg)))
(defn -main [& args]
(let [parsed-args (spec/conform ::args args)]
(if (= ::spec/invalid parsed-args)
(do (println "Bad commandline arguments")
(spec/explain ::args args))
(apply my-fun parsed-args))))
Clojure Spec来自Clojure的1.9版。