也许现在已经太晚了,但我似乎无法想出这个。我正在创造一些看起来像这样的东西
(defn new-psf
[props]
(let [psf (Psf.)]
(if (contains? props :pageLn)
(.setPageLn psf (props :pageLn)))
(if (contains? props :pageNum)
(.setPageNum psf (props :pageLn)))
(if (contains? props :includedSources)
(doseq [s (props :includedSources)]
(.add (.getIncludedSources psf) s)))
psf))
现在这看起来很丑陋,我不得不认为,重复模式在Clojure中有一种更清洁的方式。没有任何cond *函数似乎适合。我自己对用宏创建新东西不够好。
任何人都有任何想法可以让我做这样的事情:
(defn new-psf
[props]
(let [psf (Psf.)]
(condd (partial contains? props)
:pageLn (.setPageLn psf (props :pageLn))
:pageNum (.setPageNum psf (props :pageNum))
:includedSources (doseq [s (props :includedSources)]
(.add (.getIncludedSources psf) s)))
psf))
答案 0 :(得分:4)
似乎condd
与condp
几乎相同?
(defn new-psf
[props]
(let [psf (Psf.)]
(condp (contains? %2 %1) props
:pageLn (.setPageLn psf (props :pageLn))
:pageNum (.setPageNum psf (props :pageNum))
:includedSources (doseq [s (props :includedSources)]
(.add (.getIncludedSources psf) s)))
psf))
你甚至可以使用很少有用的:>> condp中的语法有一些变化:
(defn new-psf
[props]
(let [psf (Psf.)]
(condp (get %2 %1) props
:pageLn :>> #(.setPageLn psf %)
:pageNum :>> #(.setPageNum psf %)
:includedSources #(doseq [s %]
(.add (.getIncludedSources psf) s)))
psf))
答案 1 :(得分:3)
如果我读对你,第一次if
测试是否失败或成功,是否还会测试以下条件?
听起来像cond->
的工作!与condp
不同,它不会对第一场比赛进行短路评估。
(defn with-page-ln [psf v]
(.setPageLn psf v)
psf)
(defn with-page-num [psf v]
(.setPageNum psf v)
psf)
(defn with-included-sources [psf v]
(doseq [s v]
(.add (.getIncludedSources psf) s))
psf)
(defn new-psf
[props]
(cond-> (Psf.)
(contains? props :pageLn) (with-page-ln (props :pageLn))
(contains? props :pageNum) (with-page-num (props :pageLn))
(contains? props :includedSources) (with-included-sources (props :includedSources)))
答案 2 :(得分:1)
我不确定你的Psf课是什么,所以让我们在一个熟悉的课上做这个
(def frame (doto (new javax.swing.JFrame)
(.setContentPane (javax.swing.JPanel.))))
属性地图
(def props {:title "test"
:background java.awt.Color/blue
:buttons ["foo" "bar" "baz"]})
您可以使用地图
代替一系列if
(def option-application
{:title (fn [x v] (.setTitle x v))
:background (fn [x v] (.setBackground (.getContentPane x) v))
:buttons (fn [x v] (doseq [btn v] (.add x (javax.swing.JButton. btn))))})
并根据props
(doseq [[k v] props] ((k option-application) frame v))
让我们来看看我们漂亮的画面
(doto frame (.pack) (.setVisible true))
如果道具中缺少某个键,则永远不会调用option-application中的相应操作。如果订单很重要,请使用数组映射。
请注意,仍然有很多重复,因为对于每个键我都包含一个类似命名的setter。 Seesaw使用反射处理所有这些问题。请参阅那里的apply-options
,这应该足够通用,可以在课堂上使用。跷跷板也有你想借的cond-doto
。