clojure - clojure 中主机互操作点宏是如何实现的

标签 clojure clojurescript

我正在学习 clojure,并遇到了这种与主机平台互操作的语法。

(.toUpperCase "fred")
-> "FRED"
(.getName String)
-> "java.lang.String"

我很好奇这是如何实现的。文档说它们在扩展时扩展为点特殊形式,如下所示

(.instanceMember instance args*) ==> (. instance instanceMember args*)

这里似乎发生了特殊行为。通常,宏调用中的第一个参数只是宏符号。然而,在这种情况下, (. 在某种程度上是一个通用宏,它根据 (. 紧随其后的调用中的第一个参数扩展为不同的内容,就像 (. toUpperCase ...(.getName ...

那么这是如何实现的呢?实现宏是否使用了一些我不知道的特殊语法来获得该行为,或者该类型的宏实现行为在用户空间中不可用。它使用实际的宏还是读取器宏?

最佳答案

这些在手册的 Java 互操作部分 Member Accress 下进行了描述。这些是在宏扩展时扩展的特殊形式。

The instanceField form is preferred for fields and required if both a field and a 0-argument method of the same name exist. They all expand into calls to the dot operator (described below) at macroexpansion time. The expansions are as follows:

(.instanceMember instance args*)  ==> (. instance instanceMember args*)
(.instanceMember Classname args*) ==> (. (identity Classname) instanceMember args*)
(.-instanceField instance)        ==> (. instance -instanceField)
(Classname/staticMethod args*)    ==> (. Classname staticMethod args*)
Classname/staticField             ==> (. Classname staticField)

Clojure 中有多种形式的 maco:

  1. 普通类型或只是“宏”。你可以写这些。
  2. reader macros ,您可以使用 tagged literals 扩展其中一些
  3. 这些特殊形式具有宏扩展时间评估。另请参阅the expansion for the new special form

关于clojure - clojure 中主机互操作点宏是如何实现的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57488891/

相关文章:

clojure - 如何在 ClojureScript 中使用 Spectre?

clojure - 如何在 Clojure 中编译 ClojureScript

clojure - 调试 pedestal.io 应用程序的正确方法是什么?

clojure - 使用 `->`( "thread-first"宏)Clojure

java - 如何将 java 可运行示例转换为 clojure

clojure - @(在符号中)在Clojure中是什么意思?

java - 在 REPL 中使用队列文字时出现 RuntimeException

Clojurescript 宏和名称修改

javascript - ClojureScript:从 ImagaData 获取平均 RGBA 颜色

emacs - 有没有更简单的方法可以从 emacs/cider 同时使用 BOTH clj + cljs REPL?