32

注意:这与并发无关。这是关于线程宏的。

我知道->将对象放在第二个位置->>并将参数放在最后一个位置。

现在,我很好奇,就像#( ... % )函数的简写符号一样,是否有线程的简写符号可以让我将参数放置在任意位置?

目标是,不是让线程通过固定位置...我可以编写任意形式,并在特殊位置插入 %% ,而 %% 是插入线程的位置。

谢谢!

4

4 回答 4

37

从 1.5 开始,Clojure 中有一个通用的线程宏,称为as->

这条推文举例说明了它是如何工作的:https ://twitter.com/borkdude/status/302881431649128448

(as-> "/tmp" x
      (java.io.File. x)
      (file-seq x)
      (filter (memfn isDirectory) x)
      (count x))

第一个“x”绑定到“/tmp”,并用它制作一个文件。'x' 再次反弹到结果文件,并通过 'file-seq' 函数等。

于 2013-07-14T00:29:19.373 回答
26

Swiss Arrows图书馆的“钻石魔杖”可以满足您的要求:

(-<> 0
 (* <> 5)
 (vector 1 2 <> 3 4))
; => [1 2 0 3 4]

也就是说,这不是您最终经常需要的东西(或者在我的Clojure经验中)

于 2012-04-09T03:13:33.633 回答
15

万一其他人遇到这种情况,提供的宏存在是有原因的,但任意放置的宏不存在:后者会导致糟糕的 API 设计。

宏将->参数放在第一个位置。这对应于对某些主题参数起作用的函数,例如conj, assoc

宏将->>参数放在最后一个位置。这对应于对序列起作用的函数,例如map, reduce

设计好您的 API,您将不太可能需要这样的宏。

于 2012-04-09T06:18:31.847 回答
2

有一个提供此功能的库,但我忘记了在哪里。它可能在已弃用的 clojure-contrib 中。这是-$>宏。

但是您可以从 clojure 的核心-> 宏中派生出一个来制作您正在寻找的那个:

(defmacro -$>
    ([x] x)
    ([x form] (if (seq? form)
                (with-meta (map #(if (= %1 '$) x %1) form) (meta form))
                (list form x)))
    ([x form & more] `(-$> (-$> ~x ~form) ~@more)))

并使用 $ 表示插入点:

user=> (-$> 2 str (identity $) (println $))
2
nil

从技术上讲,您可以$在一种形式中使用多个。但是这种实现会多次扩展相同的表单(以换取简单性)。

于 2012-04-09T03:26:30.620 回答