对clojure不熟悉我很难为不同的代码构造找到一种惯用的风格。
在某些情况下,我的let绑定包含函数的大部分代码。这种臃肿,对clojure哲学或惯用的一些误解还不错?
这是一个示例测试用例。它测试添加/获取往返某个存储库的往返。长期看起来很奇怪吗?
(deftest garden-repo-add-get
(testing "Test garden repo add/get"
(let [repo (garden/get-garden-repo)
initial-garden-count (count (.list-gardens repo))
new-garden (garden/create-garden "Keukenhof")
new-garden-id (.add-garden repo new-garden)
fetched-garden (.get-garden repo new-garden-id)]
(is (= (+ initial-garden-count 1) (count (.list-gardens repo))))
(is (= (.name new-garden) (.name fetched-garden))))))
答案 0 :(得分:3)
我使用let
代码看到的主要问题,通常情况下,您使用的是许多中间变量,这些变量只有名称才能存在于let form
中。
避免过度使用的最佳方法是使用箭头宏->
或->>
例如,您可以使用
避免使用repo
中间变量
initial-garden-count (-> (garden/get-garden-repo)
(.list-gardens)
count)
尽管如此,在您的特定情况下,您在测试验证中使用 all 您的中间变量,因此无论如何您都需要在let语句中使用它们。也许new-garden-id
是唯一可以避免的中间人:
fetched-garden (->> (.add-garden repo new-garden)
(.get-garden repo))
或者使用Chiron建议的方法:
fechted-gaden (.get-garden repo (.add-garden repo new-garden))
答案 1 :(得分:2)
就个人而言,这就是我在Clojure中编码的方式。 Clojure简洁,优雅,简洁 我不认为通过压缩以下将是"惯用"。
(is (= (+ (count (.list-gardens repo)) 1) (count (.list-gardens (garden/get-garden-repo)))))
您的代码片段更易于理解,可以测试调试(在Eclipse中,IntelliJ ..)。
Clojure是关于简单性的,我想保持这种方式。
尽管如此,你的问题的答案仍然高度自以为是。
答案 2 :(得分:0)
通过查看你的函数代码,似乎函数正在使用的“东西”是具有getter / setter和方法的典型OO对象(参见有很多。{something}调用),这使你可以使用这些绑定因为对象API的设计方式。如果你必须使用对象,这很好。
在Clojure中,你基本上围绕数据结构设计你的API,比如map / vector / list / set和functions,这些(在大多数情况下)为你提供了一种API,它可能不需要那么多的绑定使用。