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

标签 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))

有更好的方法吗?

最佳答案

这个怎么样?

(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 ,因为这仅查看选项中传递的内容。

关于java - 在 Clojure 中执行此 Java 函数的惯用方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27308061/

相关文章:

javax.crypto.IllegalBlockSizeException : Input length must be multiple of 16 when decrypting with padded cipher in tcp

clojure - 为什么+(或*)对于零参数的行为与-(或/)不同?

clojure - Clojure 的 let 绑定(bind)形式中下划线有什么用?

list - 喜欢 first 和 rest 而不是 car 和 cdr 的 lisp 如何接近像 cdaddr 这样的组合?

java - 如何修复 Java Web 应用程序中通过发送数据泄露信息的缺陷

java - 无法初始化 native 平台。在 Jenkins

macros - 拼接非文字序列的取消引号

sqlite - 如何在 Clojure 中访问 SQLite 数据库?

java - 捕获 SqlJetException 的方法在执行后抛出 SqlJetException

java - JSF/Primefaces 数据表和排序问题