宏 -> ->> 在Clojure中

4
< p> ->->> 宏只是为了使代码更易读,还是它们还具有其他特定功能?

1个回答

7

线程优先(->)和线程最后(->>)的存在是为了使代码更易读。但这已经非常重要了!

它允许取消嵌套函数调用(取自clojuredocs的示例):

;; Arguably a bit cumbersome to read:
user=> (first (.split (.replace (.toUpperCase "a b c d") "A" "X") " "))
"X"

;; Perhaps easier to read:
user=> (-> "a b c d" 
           .toUpperCase 
           (.replace "A" "X") 
           (.split " ") 
           first)

它还可以让你强调某些内容。举个例子,考虑以下内容:
(-> {... }
    ...
    ...
    (count)) 

(count (...(... {...})))

在第一个示例中,很明显你要从地图开始,并对其进行某些操作。在第二个示例中,很明显你要计算某些东西。
偏好取决于你想要强调什么。
此外,“->”与“->>”的选择是一个清晰的视觉指示:你是否正在对集合进行操作?这一点立即变得显而易见(这是Clojure的约定,将集合作为最后一个参数)。
因此,是的,这只是可读性,但这是构建程序非常重要的一部分,而Clojure提供了使代码自然阅读的工具。在选择一种解决方案时,我尝试考虑Clojure的阅读方式。

2
值得注意的是,还有一系列相关的条件线程宏,它们在上述基础上添加了额外的功能。some->some->> 线程首尾,但如果任何步骤返回 nil,则停止评估,就像 maybe monad 一样。cond->cond->> 测试条件以决定是否将值传递到每个线程化形式中。 - Magos
1
@nha 谢谢,现在非常清晰了! 顺便问一下,在您的完美答案中我有一个新问题:方法名称前的点是否表示Java方法? (例如 .replace .toUpperCase),调用Java方法和Clojure库之间是否有任何区别或好处:(clojure.string/replace) (clojure.string/upper-case) - user4813927
@AmirTeymuri,很高兴你喜欢它 :) 是的,那些是Java方法(我只是从clojuredocs中取了例子,但是Clojure方法更符合习惯)。此外,在调用不在Clojure名称空间中的Java方法时,您可能会对doto宏感兴趣。 - nha
为什么要把它命名为“线程”,当它更像是“管道”呢? - Frank C.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接