请在 2024 年 Clojure 情况调查 中分享您的想法!

欢迎!请查看 关于 页面了解此功能的工作原理。

0
ClojureScript

^:export 似乎对 defrecord 没有影响 - 我只看到 Closure 发射了 def 和 defn 的原始符号。

我认为类似地,deftype、defprotocol 等也可能是合理的目标。

无论如何,最好明确说明什么有效,什么目前无效(advanced-compilation.adoc),以免人们盲目尝试。

6 答案

0

评论者:mfikes

可以导出协议方法。建议网站更改:[链接](https://github.com/clojure/clojurescript-site/pull/148)

0
_评论者:mfikes_

{{^:export}} 仅在 Vars 上工作。

协议方法是 Vars,因此上述网站更改将有助于阐明如何导出它们。

考虑中的其他 Vars 将是用于为 {{defrecord}} 和 {{deftype}} 生成合成的映射和位置工厂函数以及构造函数。

或许可以通过更改将接受这样的方式:{{(defrecord ^:export Foo [])}} 导出 {{map->Foo}}、{{->Foo}} 和 {{Foo}}。同样,{{(deftype ^:export Bar [])}} 导出 {{->Bar}} 和 {{Bar}}。
0

评论者:mfikes

解决方案:使用 {{goog/exportSymbol}}

`
(ns my-ns.core)

(defrecord Foo [])
(goog/exportSymbol "my_ns.core.mapGT_Foo" my_ns.core.mapGT_Foo)
(goog/exportSymbol "my_ns.core.GT_Foo" my_ns.core.GT_Foo)
`

0

评论者:vemv

嗨 Mike,

非常感谢你澄清并解决这个问题!非常感激。

?: ^:export 仅在 Vars 上工作。

在我看来,这应该是一个可以包含在文档中的优秀知识点。为什么不把整个故事放在一个地方讲述呢?

让我提出这个问题的原始担忧是记录/调试。

假设一个应用程序有一系列单例的 defrecord 实例,作为“组件”系统(Sierra 风格)的一部分。

然后,对于记录,我可能会想用 {{(js/console.log (type the-instance))}} 来识别一个有缺陷的组件。

但没有语言支持,一个人无法在没有大量样板代码或可能是一个黑客宏的情况下使其工作。

在高级编译中,是否可以让 {{(type some-instance-of-a-defrecord-or-deftype)}} 打印原始名称?

0
_评论者:mfikes_

嗨 Victor,

感谢您对票据意图的澄清。{{\^:export}} 不是用于调试,而是用于将未经重命名的符号提供给 JavaScript。实际上,它不会更改重命名的优化 JavaScript,而是简单地提供了额外的未经重命名的别名,这些别名指向优化/重命名的代码。(因此,通常,调试涉及重命名的/优化的代码,即使旁边有未经重命名的 {{^:exports}}。)

幸运的是,存在 {{:pseudo-names}} 来帮助调试优化代码:[链接](https://script.clojure.org/reference/compiler-options#pseudo-names)

对于您的记录实例类型的示例,例如在 Node.js 中,如果没有启用 {{:pseudo-names}},您将得到 {{[Function: ze]}},如果启用了 {{:pseudo-names}},您将得到 {{[Function: $my_ns$core$Foo$$]}}。

我已经对网站提出了修订:[链接](https://github.com/clojure/clojurescript-site/pull/150)

如果 {{:pseudo-names}} 满足这个问题的需求,也许这个任务可以被关闭。
0
参考:[链接](https://clojure.atlassian.net/browse/CLJS-2406)(由 alex+import 提出)
...