首页 文章

Leiningen命令args解析

提问于
浏览
1

我是Clojure的新手,我对leib命令行args有一个问题我无法解决 . 我的应用很简单:

(defn -main
  [& args]
  (println (apply hash-map args))
  (let [{:keys [f w h]} (apply hash-map args)]
    (println f w h)
;     (init-frame w h)
;     (draw-values f w h)
))

终端输出:

lein run :f bit-xor :w 200 :h 200
{:w 200, :h 200, :f bit-xor}
nil nil nil

当我从REPL运行-main时效果很好 . 当我在core.clj中定义一个hashmap时,这样做也很好 .

(def my-args (hasmap :f "bit-xor" :w 200 :h 200))

我无法弄清楚,为什么我的'f','w'和'h'让我们变得零 . 有人可以帮忙吗?

我做了一个特殊的小应用程序只是为了测试 .

(ns cmdargs.core
 (:gen-class))

(defn -main
 [& args]
 (println "args: " args)
 (println "args map: " (apply hash-map args))
 (println "param keys: " (keys (apply hash-map args)))
 (println "param vals: " (vals (apply hash-map args)))
 (let [{:keys [param1 param2]} (apply hash-map args)]
   (println "param1: " param1)
   (println "param2: " param2)))

REPL输出:

cmdargs.core> (-main :param1 200 :param2 300)
 args:  (:param1 200 :param2 300)
 args map:  {:param2 300, :param1 200}
 param keys:  (:param2 :param1)
 param vals:  (300 200)
 param1:  200
 param2:  300
 nil
 cmdargs.core>

终端/ lein输出:

cmdargs$ lein run :param1 200 :param2 300
 Java HotSpot(TM) Client VM warning: TieredCompilation is disabled in this release.
 Java HotSpot(TM) Client VM warning: TieredCompilation is disabled in this release.
 args:  (:param1 200 :param2 300)
 args map:  {:param1 200, :param2 300}
 param keys:  (:param1 :param2)
 param vals:  (200 300)
 param1:  nil
 param2:  nil

2 回答

  • 1

    :keys 解构仅适用于关键字,您认为通过 -main 进入的关键字实际上不是关键字而是字符串,每个字符串都以冒号开头 . 要确认这一点,请使用函数 type 来获取参数 .

    https://clojure.org/guides/destructuring我发现这个引用:

    :keys键用于带关键字键的关联值

    如果确实需要将传入参数转换为关键字,请使用 keyword

    (keyword (subs ":f" 1))
    

    所以在你的情况下你可能会这样做:

    (map (comp keyword #(subs % 1)) [":f" ":w" ":h"])
    

    ,但不是 [":f" ":w" ":h"] ,你会有 args .

    当然,如果您决定省略冒号,在Clojure读者之外没有意义,事情会变得更简单:https://clojure.org/reference/reader .

  • 0

    谢谢! REPL和Lein差别解释'args'有点令人困惑 .

    REPL解释':param1'

    -main :param1 200

    clojure.lang.Keyword

    但在莱因

    lein run :param1 200

    进入 'java.lang.String' .

    我已经尝试了:strs而不是:key更早但忘记了冒号 . 这是有效的:

    (defn -main
     [& args]
     (let [{:strs [:param1 :param2]} (apply hash-map args)]
     (println "param1: " param1)
     (println "param2: " param2)))
    

    当然,在这种情况下,param之前的冒号并不意味着什么 .

    对于:键我已完成以下操作

    (defn -main
      [& args]
    
      (let [{:keys [param1 param2]} 
         (into {} (for [[k  v] (apply hash-map args)]
                       [(keyword (apply str (rest k))) v]))]
      (println "param1: " param1)
      (println "param2: " param2)))
    

相关问题