简体   繁体   English

如何在 Clojure 中使用命令行参数?

[英]How to use command line arguments in Clojure?

I'm working my way through one of my first Clojure programs.我正在研究我的第一个 Clojure 程序。 The one thing I have left to do is have my program accept command line arguments.我剩下要做的一件事是让我的程序接受命令行参数。 The number of args can vary (but needs to be at least one), and then each command line arg needs to be provided as an argument to a function in my main , one at a time. args 的数量可以变化(但至少需要一个),然后每个命令行 arg 需要作为参数提供给我的main的函数,一次一个。 I've been reading online and it seems that clojure/tools.cli is the way to do it, (using parse-opts maybe?).我一直在网上阅读,似乎clojure/tools.cli是这样做的方法,(可能使用parse-opts ?)。 But I can't figure it out for the life of me.但我无法弄清楚我的生活。 There's no validation, really that needs to happen -- whatever the user would provide would be valid.没有验证,确实需要进行验证——用户提供的任何内容都是有效的。 (The only thing that needs to be checked is that there is at least one argument provided). (唯一需要检查的是至少提供了一个参数)。 Any suggestions on how to go about this?关于如何解决这个问题的任何建议?

All the examples I run into seem very complicated and go over my head very easily.我遇到的所有示例看起来都非常复杂,而且很容易让我无法理解。

An easy example of what I'm trying to do is after a user provides any number of command line arguments, then have clojure print each string in a new line of the terminal.我正在尝试做的一个简单示例是在用户提供任意数量的命令行参数之后,然后让 clojure 在终端的新行中​​打印每个字符串。

I use leiningen to run my programs.我使用 leiningen 来运行我的程序。

The easy way is to use clojure.core/*command-line-args* :简单的方法是使用clojure.core/*command-line-args*

(doseq [arg *command-line-args*]
  (println (str "Read an argument: " arg)))

Since your entire question seems to boil down to:由于您的整个问题似乎归结为:

An easy example of what I'm trying to do is after a user provides any number of command line arguments, then have clojure print each string in a new line of the terminal.我正在尝试做的一个简单示例是在用户提供任意数量的命令行参数之后,然后让 clojure 在终端的新行中​​打印每个字符串。

I'll answer that.我会回答那个。 That can be done fairly succinctly:这可以相当简洁地完成:

(defn -main [& args] ; & creates a list of var-args
  (if (seq args)
    ; Foreach arg, print the arg...
    (doseq [arg args]
      (println arg))

    ; Handle failure however here
    (throw (Exception. "Must have at least one argument!"))))

Note, unless you absolutely want to fail outright when 0 arguments are passed, you can skip the seq check.请注意,除非您绝对想在传递 0 个参数时彻底失败,否则您可以跳过seq检查。 doseq won't run if args is empty since there isn't anything to iterate over.如果args为空,则doseq将不会运行,因为没有任何要迭代的内容。

You can also replace the whole doseq with:您还可以将整个doseq替换为:

(mapv println args)

But that's arguably an abuse of mapv .但这可以说是对mapv的滥用。

Clojure Spec can do many things, and parsing and validating command line arguments is one of those things. Clojure Spec可以做很多事情,解析和验证命令行参数就是其中之一。 Here is an example:下面是一个例子:

(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 ships from version 1.9 of Clojure. Clojure Spec 从 Clojure 1.9 版开始提供。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM