我正在学习 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:
- 普通类型或只是“宏”。你可以写这些。
- reader macros ,您可以使用 tagged literals 扩展其中一些
- 这些特殊形式具有宏扩展时间评估。另请参阅the expansion for the new special form
关于clojure - clojure 中主机互操作点宏是如何实现的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57488891/