Clojure的隐藏功能

dan*_*lei 27 clojure

您发现自己使用哪些鲜为人知但有用的Clojure功能?随意分享小技巧和习语,但试着限制你自己的核心和贡献.

我在这些类似问题的答案中找到了一些非常有趣的信息:

对于其他语言,还有更多的"隐藏功能"问题,所以我认为为Clojure设置一个也很好.

Bri*_*per 23

Clojure有一个不可变的,持久的队列数据类型PersistentQueue,但它(但是?)没有文字阅读器语法或Clojure包装函数,所以你必须通过Java调用创建一个.队列结合(推)到后面并从前面弹出,性能良好.

user> (-> (clojure.lang.PersistentQueue/EMPTY)
          (conj 1 2 3)
          pop)
(2 3)
Run Code Online (Sandbox Code Playgroud)

列在前面,从前面弹出.矢量组合到后部并从后部弹出.所以队列有时候正是你所需要的.

user> (-> ()
          (conj 1 2 3)
          pop)
(2 1)
user> (-> []
          (conj 1 2 3)
          pop)
[1 2]
Run Code Online (Sandbox Code Playgroud)


dno*_*len 13

(defn foo [a & [b c]] ...)
Run Code Online (Sandbox Code Playgroud)

你可以解构其余的论点.

更新:

git repo的最新提交(29389970bcd41998359681d9a4a20ee391a1e07c)使得执行关联解构成为可能,如下所示:

(defn foo [a & {b :b c :c}] ...)
Run Code Online (Sandbox Code Playgroud)

显而易见的用于关键字参数.请注意,这种方法可以防止将关键字参数与其他参数混合使用(而不是那些可能经常需要的东西).

(defn foo [a & {:keys [b c] :or {b "val1" c "val2"}] ...)
Run Code Online (Sandbox Code Playgroud)

如果您想要关键字参数的默认值.


Art*_*ldt 11

read-eval阅读器宏: #=

(read-string "#=(println \"hello\")")
Run Code Online (Sandbox Code Playgroud)

如果read用于用户输入(这可能是一个坏主意),这个宏可能会带来安全风险.您可以通过设置*read-eval*为关闭此宏false.


Raf*_*ird 8

您可以apply使用无限参数序列.例如

(apply concat (repeat '(1 2 3)))
Run Code Online (Sandbox Code Playgroud)

产生一个懒惰的序列1,2,3,1,2,3 ...当然,为了使它工作,该函数也必须相对于其参数列表是懒惰的.

  • @nickik:当然 - `(重复'(1 2 3))`只是作为一个无限的序列序列来表示`(apply concat ...)`的工作原理. (2认同)

Ale*_*ard 6

来自越来越好的ClojureDocs网站使用http://clojuredocs.org/clojure_core/clojure.core/juxt成语juxt

;juxt is useful for forking result data to multiple termination functions
(->> "some text to print and save to a file"
  ((juxt
     println
     (partial  spit "useful information.txt"))))