Clojure的隐藏特性

27
5个回答

23

Clojure拥有一个不可变的持久队列数据类型PersistentQueue,但它尚未具有字面读取器语法或Clojure包装函数,因此您必须通过Java调用来创建一个。 队列使用良好的性能在后面进行conj(推)操作,并从前面进行pop操作。

user> (-> (clojure.lang.PersistentQueue/EMPTY)
          (conj 1 2 3)
          pop)
(2 3)

将项目添加到列表的前面并从列表前端删除。向向量的末尾添加项目并从向量的末尾弹出项目。因此,队列有时正是您所需要的。

user> (-> ()
          (conj 1 2 3)
          pop)
(2 1)
user> (-> []
          (conj 1 2 3)
          pop)
[1 2]

哇。从列表中弹出100,000个项目,我的电脑只需要大约12毫秒。将列表转换为队列并弹出所有内容需要约0.2毫秒。这对我正在编写的程序非常有帮助。 - MBCook

13
(defn foo [a & [b c]] ...)
你可以使用解构赋值来处理剩余参数。
更新:
最新的提交到git仓库(29389970bcd41998359681d9a4a20ee391a1e07c)使得可以执行关联解构,如下:
(defn foo [a & {b :b c :c}] ...)

这个方法的明显用途是用于关键字参数。注意,这种方法防止将关键字参数与剩余参数混合使用(不过这不是经常需要的事情)。

(defn foo [a & {:keys [b c] :or {b "val1" c "val2"}] ...)

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


11

读取-求值的读取宏:#=

(read-string "#=(println \"hello\")")

如果在用户输入上使用read(本身可能是一个糟糕的想法),则此宏可能会带来安全风险。您可以通过将*read-eval*设置为false来关闭此宏。


8
你可以将函数应用于无限的参数序列。例如:
(apply concat (repeat '(1 2 3)))

该函数生成一个惰性序列,包含1,2,3,1,2,3...。当然,为了使该函数正常工作,它还必须对其参数列表进行惰性处理。


1
有一种更好的方法来完成这个任务 (cycle '(1 2 3)) - nickik
2
@nickik:当然 - (repeat '(1 2 3)) 只是一个无限序列的序列的示例,以展示 (apply concat ...) 的工作原理。 - Rafał Dowgird

6

从越来越好的ClojureDocs网站上,有一个使用juxt的习惯用法

juxt http://clojuredocs.org/clojure_core/clojure.core/juxt非常有用,可以将结果数据分叉到多个终止函数中。
(->> "一些要打印并保存到文件的文本"
  ((juxt
     println
     (partial spit "useful information.txt"))))

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