- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在回答 another question我在 Clojure 的可变参数函数 args 中遇到了一些我没想到的东西:
user=> (defn wtf [& more] (println (type more)) :ok)
#'user/wtf
;; 1)
user=> (wtf 1 2 3 4)
clojure.lang.ArraySeq
:ok
;; 2)
user=> (let [x (wtf 1 2 3 4)] x)
clojure.lang.ArraySeq
:ok
;; 3)
user=> (def x (wtf 1 2 3 4))
clojure.lang.PersistentVector$ChunkedSeq
#'user/x
user=> x
:ok
ArraySeq
在 1) 和 2) 中,但
PersistentVector$ChunkedSeq
在 3)?
最佳答案
简短回答:这是 Clojure 的一个模糊的实现细节。该语言唯一保证的是可变参数函数的剩余参数将作为 clojure.lang.ISeq
的实例传递。 , 或 nil
如果没有其他参数。你应该相应地编码。
长答案:它与函数调用是编译还是简单评估有关。无需详细讨论评估和编译之间的区别,只要知道 Clojure 代码被解析为 AST 就足够了。根据上下文,可以直接评估 AST 中的表达式(类似于解释),或者可以编译成 Java 字节码作为动态生成类的一部分。后者发生的典型情况是在 lambda 表达式的主体中,它将评估为实现 IFn
的动态生成类的实例。界面。见Clojure documentation有关评估的更详细说明。
绝大多数情况下,编译代码和评估代码之间的差异对您的程序来说是不可见的;它们的行为方式完全相同。这是编译和评估导致行为略有不同的罕见极端情况之一。不过,重要的是要指出,这两种行为都是正确的,因为它们符合语言所做的 promise 。
Clojure 代码中的函数调用被解析为 InvokeExpr
的实例在 clojure.lang.Compiler
.如果正在编译代码,则编译器会发出字节码,该字节码将调用 invoke
IFn
上的方法使用适当的数量( Compiler.java, line 3650 )的对象。如果代码只是被评估而不是编译,那么函数参数被捆绑在一个 PersistentVector
中。并传递给 applyTo
IFn
上的方法对象(Compiler.java, line 3553)。
具有可变参数列表的 Clojure 函数被编译为 clojure.lang.RestFn
的子类。类(class)。该类实现了IFn
的所有方法,收集参数,并发送到适当的 doInvoke
arity。您可以在 applyTo
的实现中看到也就是说,在需要 0 个参数的情况下(就像您的 wtf
函数中的情况),输入 seq 被传递给 doInvoke
方法并且对函数实现可见。 invoke
的 4 参数版本同时,将参数捆绑在 ArraySeq
中并将其传递给 doInvoke
方法,所以现在您的代码会看到 ArraySeq
.
更复杂的是,Clojure 的 eval
的实现函数(这是 REPL 正在调用的函数)将在内部包装一个正在评估的列表表单(一个匿名的、无参数的函数),然后编译并执行该 thunk。所以几乎所有的调用都使用了对 invoke
的编译调用。方法,而不是由编译器直接解释。 def
有一个特殊情况无需编译即可显式评估代码的表单,这说明了您在那里看到的不同行为。clojure.core/apply
的执行也调用applyTo
方法,并通过这个逻辑传递给 apply
的任何列表类型应该看到函数体。确实:
user=> (apply wtf [1 2 3 4])
clojure.lang.PersistentVector$ChunkedSeq
:ok
user=> (apply wtf (list 1 2 3 4))
clojure.lang.PersistentList
:ok
关于types - 为什么 Clojure 变量 arity args 会根据用途获得不同的类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26042835/
XML可以应用于 WEB 开发的许多方面,常用于简化数据的存储和共享 XML 把数据从 HTML 分离 现在的HTML 文档一般都是显示动态数据,每当数据改变时将花费大量的时间来编辑 HTML
在类(class)(方案)中,我们最近学习了允许函数接受任意数量参数的语法,例如; (define len (lambda args (length args))) >(len 1 2 3
在 redis-cli 中执行 info 命令时,会列出与该服务器相关的所有信息。 “evicted_keys”的目的是什么? 最佳答案 Redis 可以配置为根据需要自动清除键。如果这样配置,red
golang 空结构体 struct{} 可以用来节省内存 ? 1
有人可以解释一下资源文件夹中的 Info.plist 是什么吗?我如何在我的应用程序中使用它?提前致谢。 最佳答案 您可以在Info.plist文件中为所有类型的设备指定不同的常规资源和应用程序配置,
我需要减小可执行文件的大小,并且经常在我的可执行文件中将某些“不必要的” uses占用一定的大小。 例如: Unit1连接到Unit2,但是两个单元的导入为“ System.SysUtils”。 然后
我是 OOP 的新手。虽然我了解多态是什么,但我无法真正使用它。我可以有不同名称的函数。为什么我应该尝试在我的应用程序中实现多态性。 最佳答案 在严格类型化的语言中,多态性对于拥有不同类型对象的列表/
Possible Duplicate: What is the difference between a delegate and events? Possible Duplicate: Differ
这个问题在这里已经有了答案: Custom index.html javadoc page? (2 个答案) 关闭 7 年前。 我使用的是eclipse。一般情况下我们可以使用javadoc.exe
你能解释一下吗ValidateAntiForgeryToken目的并向我展示有关 MVC 4 中的 ValidateAntiForgeryToken 的示例? 我找不到任何解释此属性的示例? 最佳答案
我正在学习 RxSwift 并试图了解 Observable 和 PublishSubject aka Sequence 之间的主要区别。 据我了解,Sequences/PublishesSubjec
有时有人说,在使用 Azure 表时,实际上存在第三个关键分区数据 - 表名称本身。 我在执行分段查询时注意到 TableContinuationToken 有一个 NextTableName 属性。
在Apple提供的aurioTouch项目中,听说在performRender()函数下的AudioController文件中的AudioBufferList ioData携带了mic到音频播放器的音
MSDN 文档没有详细解释它的用途。 由于它是可选的,我几乎假设它类似于某种元数据。 我现在如何看待它,我想用它来为特定用户指定缓存,例如: new CacheItem(key: "keyName",
我正在学习 browserify,我正在尝试用它做两件基本的事情: 转换(通过 shim)非 CommonJS 模块以实现易用性和依赖跟踪 捆绑项目特定的库 我找到了一个工作流程,说明如何使用 Gul
我通过按 CTRL + C 访问 eix 1.8.2 的 Break 菜单。它看起来像这样: BREAK: (a)bort (c)ontinue (p)roc info (i)nfo (l)oaded
在 codeLabs 教程(Android - Kotlin - Room with a View)中,他们使用“viewModelScope.launch(Dispatchers.IO)”来调用插入
我通过按 CTRL + C 访问 eix 1.8.2 的 Break 菜单。它看起来像这样: BREAK: (a)bort (c)ontinue (p)roc info (i)nfo (l)oaded
请耐心等待,因为我没有太多地使用压缩算法,所以这对你们中的一些人来说可能是显而易见的。当某些流媒体视频开始滞后时,我总是注意到这一点。当我看到这个问题时我才意识到我很好奇: Twitter image
关闭。这个问题是opinion-based 。目前不接受答案。 想要改进这个问题吗?更新问题,以便 editing this post 可以用事实和引文来回答它。 . 已关闭 3 年前。 Improv
我是一名优秀的程序员,十分优秀!