在Clojure中执行此Java函数的惯用方法是什么?

时间:2014-12-05 03:04:00

标签: java clojure

我将这个Java函数复制到Clojure中。

Config createConfig(Map<String, String> options) {
  Config conf = new Config();
  String foo = options.get("foo");
  if (foo != null) { conf.setFoo(foo); }
  String bar = options.get("bar");
  if (bar != null) { conf.setBar(bar); }
  // many other configs
  return conf;
}

我想出了这个,

(defn create-config [options]
  (let [conf (Config.)]
    (when-let [a (:foo options)] (.setFoo a))
    (when-let [a (:bar options)] (.setBar a))
    conf))

有更好的方法吗?

2 个答案:

答案 0 :(得分:2)

这个怎么样?

(defn create-config [{:keys (foo bar)}]
  (let [config (Config.)]
    (when foo (.setFoo config foo))
    (when bar (.setBar config bar))))

可能更好的方法是创建一个可以根据Clojure贴图在对象上设置任意数量字段的通用宏。这可能更漂亮,但它确实有效:

(defmacro set-fields 
  [options obj]
  (let [o (gensym)
        m (gensym)]
    `(let [~m ~options
           ~o ~obj]
       ~@(map (fn [[field value]]
                (let [setter (symbol (str "set" (clojure.string/capitalize (name field))))]
                  `(. ~o (~setter ~value))))
               options)
       ~o)))

;; call like:
(set-fields {:daemon true :name "my-thread"} (Thread.))

;; translates to:
;; (let [G__1275 {:daemon true, :name "my-thread"} 
;;       G__1274 (Thread.)]
;;   (. G__1274 (setDaemon true))
;;   (. G__1274 (setName "my-thread"))
;;   G__1274)

我没有检查null,因为这只会查看选项中传递的内容。

答案 1 :(得分:0)

也许结帐some->>

fillertext fillertext