Clojure中如何打印对象引用的值?

发布于 2025-01-14 09:09:24 字数 198 浏览 1 评论 0原文

每当我在 REPL 上输入以下内容时,

(defn test_function
    []
    ()
)

输出是 -

#'clojure.repl/test_function

由于函数是 Clojure 中的对象,如何获取引用该函数对象的引用的值?

Whenever I type the following on the REPL

(defn test_function
    []
    ()
)

The output is -

#'clojure.repl/test_function

As functions are objects in Clojure, how to get the value of the reference that refers to this function object?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

雨轻弹 2025-01-21 09:09:25

在 Clojure 中,Var(Java 类是 clojure.lang.Var)是一个容器,您可以在其中存储任何不可变值。您甚至可以稍后将不同的不可变值存储到此容器中 - 但是,现在让我们忽略它。可以使用名称(也称为符号)来引用容器。名称和 Var 之间的映射存储在每个命名空间中。因此,当您说

(defn testf [] ())

that (或多或少)相当于

(def testf (fn [] ()))

That 将创建一个 Var,将新创建的函数对象存储到该 Var 中,并在符号 testf 和 Var 之间创建映射。您只需评估符号即可获得函数对象。因此,

user=> testf
#object[user$test_function 0x67207d8a "user$testf@67207d8a"]
user=> (class testf)
user$testf

这告诉您该函数是 user$testf 类的 Java 对象。

如果您想检查 Var 本身(而不是它包含的值),您可以执行以下操作

user=> (var testf)
#'user/testf
user=> (class (var testf))
clojure.lang.Var

,告诉您 Var 是 #'user/testf 以及实现 Clojure 的 Java 类Var 是 clojure.lang.Var。

您可能会受益于阅读Clojure - 变量和全球环境或了解更多详细信息的来源。

最后回答你的问题......你可以将 Var 视为对象引用的持有者。在这种情况下,您可以通过计算 (var foo) 来“打印”绑定到符号 foo 的 Var。您可以通过评估 foo 来“打印”对象本身。

In Clojure, a Var (the Java class is clojure.lang.Var) is a container in which you can store any immutable value. You can even store a different immutable value into this container at a later time - but, for now, let's ignore that. The container can be referred to using a name (aka symbol). The mapping between the name and the Var is stored in each namespace. So, when you say

(defn testf [] ())

that is (more or less) equivalent to

(def testf (fn [] ()))

That will create a Var, store the newly created function object into that Var, and create a mapping between the symbol testf and the Var. You can get the function object by just evaluating the symbol. Thus

user=> testf
#object[user$test_function 0x67207d8a "user$testf@67207d8a"]
user=> (class testf)
user$testf

That tells you that the function is a Java object of the class user$testf.

If you want to inspect the Var itself (rather than the value that it contains), you can do the following

user=> (var testf)
#'user/testf
user=> (class (var testf))
clojure.lang.Var

which tells you that the Var is #'user/testf and the Java class that implements a Clojure Var is clojure.lang.Var.

You might benefit from reading Clojure - Vars and the Global Environment or the sources for more details.

To finally answer your question ... you can consider the Var as the holder to a reference to the object. In that case, you can "print" the Var that is bound to a symbol foo by evaluating (var foo). And you can "print" the object itself by evaluating foo.

旧梦荧光笔 2025-01-21 09:09:25

如果您加载源代码,Clojure 会将您的代码编译为 JVM 字节代码
文件,并且没有办法创建类来做到这一点
(除了原始类型之外的所有类型都是 JVM 中的对象后代)。

如果您查看 uberjar,您可以看到很多正在发生的事情
您的 lein 项目或者您 AOT 编译 clj 文件。

您可以从函数中获取 class

(defn test-function []
  (println :hello))

(println (class test-function))
; ⇒ user$test_function

$ 表示使用了一个内部类;这只是
一个公约。此外,- 已更改为 _,clojure 称之为
“咀嚼”。

现在您可以创建该类的新实例,并且可以.invoke
(因为它实现了
IFn
界面):

(let [tf (new user$test_function)]
  (.invoke tf))
; ⇒ :hello

Clojure compiles your code down to JVM byte code if you load source
files and there is no way around to create classes to do that
(everything except primitive types is an Object descendant in the JVM).

You can see lot's of what is going on, if you check out an uberjar of
your lein project or if you AOT compile clj files.

You can get the class from your function:

(defn test-function []
  (println :hello))

(println (class test-function))
; ⇒ user$test_function

The $ indicates, that there is an inner class used; this is just
a convention. Also the - has changed to a _, which clojure calls
"munging".

Now you can create a new instance of that class and you can .invoke it
(as it's implements the
IFn
interface):

(let [tf (new user$test_function)]
  (.invoke tf))
; ⇒ :hello
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文