我正在阅读Clojure的喜悦,在有关瘫痪的部分中,解释了功能pvalues
,pmap
和pcalls
的功能,并简要示例说明了如何使用每个功能。以下是pvalues
和pcalls
给出的示例:
(defn sleeper [s thing] (Thread/sleep (* 1000 s)) thing)
(pvalues
(sleeper 2 :1st)
(sleeper 3 :2nd)
(keyword "3rd"))
(pcalls
#(sleeper 2 :1st)
#(sleeper 3 :2nd)
#(keyword "3rd"))
我了解两个-pvalues
之间的技术差异要计算一个可变数量的"值",而pcalls
则采用"任意数量的函数无参数",并在并行中调用。在这两种情况下,返回结果的懒惰序列。
我的问题本质上是,您什么时候使用一个与另一个使用?似乎唯一的语义差异是您在每个参数之前将#
粘贴到pcalls
,将其变成匿名函数。因此,纯粹是从保存击键并拥有更简单的代码的角度,只使用pvalues
是否更有意义? - 如果是这样,为什么甚至具有pcalls
函数?
我可以用pcalls
来获得它,您可以替换一个指称函数的符号,但是如果您想与pvalues
一起使用此类函数,则可以将功能放入括号中,以便将其称为。
我对Clojure为什么具有如此相似的两个函数的原因有些困惑。您可以使用一个,而是另一个可以做什么?一些人为的示例可能会有所帮助。
pvalues是围绕pcalls周围的说明宏,尽管由于宏不是一流的,它不能像函数一样可以组合或传递。这是一个只有PCALLS的示例:
user> (defn sleeper [s thing] (Thread/sleep (* 1000 s)) thing)
#'user/sleeper
user> (def actions [#(sleeper 2 :1st) #(sleeper 3 :2nd) #(keyword "3rd")])
#'user/actions
user> (apply pcalls actions)
(:1st :2nd :3rd)
user> (apply pvalues actions)
CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/pvalues, compiling:(NO_SOURCE_PATH:1:1)
在设计API时,重要的是,您不会限制用户仅通过宏与库进行交互,因为那时他们会受到这样的限制。