请在 2024 年 Clojure 状态调查! 中分享您的想法。

欢迎!有关如何使用本页的更多信息,请参阅 关于 页面。

0
Clojure

Vars 虽然是一种通用的引用结构,但用于实现绑定,并且有特殊的读取器和打印机表示法,反映了这种现实。与 Keywords 和 Symbols 不同,Vars 在打印时虽然表现出命名,但实际上并没有实现 clojure.lang.Named 接口。

附带的补丁实现了 Vars 上的命名。

示例

`
user=> (name :clojure.core/conj)
"conj"
user=> (namespace :clojure.core/conj)
"clojure.core"
user=> (name 'clojure.core/conj)
"conj"
user=> (namespace 'clojure.core/conj)
"clojure.core"
user=> (name #'clojure.core/conj)
"conj"
user=> (namespace #'clojure.core/conj)
"clojure.core"
user=> (with-local-vars [x 1] (name x))
"--unnamed--"
user=> (with-local-vars [x 1] (namespace x))
nil
user=> (with-local-vars [x 1] (println x))

<Var: --unnamed-->

`

这在如 CinC 项目这样的应用程序中很有用,其中 Vars 经常直接用作值,在这些场景中,它们理想上可以与表示它们的符号值互换。

7 答案

0

由 bronsa 发表的评论:

使用此补丁调用 name 不会命名的 Var 将导致 NPE,我认为这不是所需行为。

0

由 arrdem 发表的评论:

我同意,然而这种行为似乎在 Core 中是标准的。

Clojure 1.6.0
user=> (name nil)
NullPointerException clojure.core/name (core.clj:1518)
user=> (namespace nil)
NullPointerException clojure.core/namespace (core.clj:1526)

我也并不相信未绑定变量的“名称”或“命名空间”是有意义的,在这种情况下,NPE(空指针异常)可能是可以接受的。

0

由 bronsa 发表的评论:

我讨论的并不是未绑定变量,而是匿名变量,我猜你写错了。

我同意你的看法,抛出异常可能是一种合理的行为,但是我可以在调用它的name方法之前测试是否为nil,而对于一个变量是否命名,目前还没有任何方法可以测试,除了尝试直接访问.name字段,这正是这个工单的目的。

0

由 bronsa 发表的评论:

我与Reid在IRC上讨论了这个问题,以下是讨论结果
变量可以是未命名的(与with-local-vars返回的变量一样),或者包含命名空间和名称部分(这是interned变量的情况)
目前没有方法可以测试变量的“internedness”,因此访问变量的.name或.namespace字段,测试是否为nil是目前唯一的可行方法

鉴于上述情况,当前的补丁似乎不太满意,以下是一些提议的解决方案
使变量可命名,当未命名的变量调用namespace时返回nil,当名称调用时返回"--unnamed--"
保持变量不实现Named,添加一个"var-symbol"函数,返回一个与变量ns+name匹配的命名空间符号,或者在未命名的变量上返回nil

我个人更倾向于第二种解决方案,因为我认为变量不应该可命名,因为它们可以是未命名的,这在我看来是一种矛盾。

0

由 arrdem 发表的评论:

添加了处理未绑定变量情况的补丁。

0

由 arrdem 发表的评论:

将所有补丁压缩到一个diff文件中,并更新了附件。

0
参考:[https://clojure.atlassian.net/browse/CLJ-1488](https://clojure.atlassian.net/browse/CLJ-1488)(由arrdem报告)
...