我查看了lazy-seq的来源,发现了以下内容:
Clojure 1.4.0
user=> (source lazy-seq)
(defmacro lazy-seq
"Takes a body of expressions that returns an ISeq or nil, and yields
a Seqable object that will invoke the body only the first time seq
is called, and will cache the result and return it on all subsequent
seq calls. See also - realized?"
{:added "1.0"}
[& body]
(list 'new 'clojure.lang.LazySeq (list* '^{:once true} fn* [] body)))
nil
user=>我想知道fn*与fn有什么不同,但我似乎在文档中找不到对fn*的任何引用。我错过了什么,fn*又有什么不同?
发布于 2014-05-11 00:33:10
免责声明:我离Clojure编译器专家还有很长的一段路要走,所以用适当数量的盐来看下面的内容。
fn*是fn的一个固有版本。Clojure的大部分都是用Clojure实现的,但是一些低级别的函数是用Java实现的;fn*就是其中之一。
fn是用fn*实现的。消息来源如下:
https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L42
fn*在编译器中实现:
https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compiler.java#L47
实际上,fn*有两个不同的版本,它们在Java中被符号FN和FNONCE所引用。第一个是“裸”fn*,第二个是带有元数据^{:once true}的fn*,元数据^{:once true}是lazy-seq使用的版本。
^{:once true}用于让编译器知道包含函数的闭包只会被调用一次,并且它可以执行封闭的本地清除。有关更多详细信息,请参阅this mailing list thread。
https://stackoverflow.com/questions/23586710
复制相似问题