clojure - Clojure 中的参数传递是如何工作的?

标签 clojure

我知道在Java中,如果我将一个对象作为参数传递给方法,那么该方法将使参数变量指向同一个对象,而不是复制。在 Clojure 中怎么样?例如:

(defn print-from-reader [rdr]
   (print (.read rdr)))

(...inside some code...
  (with-open [rdr (Reader file)]
    (print-from-rader rdr)))

当 rdr 传入时,print-from-reader 是否会在内存中创建 rdr 的另一个副本,或者它指向已由 with-open 绑定(bind)创建的同一个 rdr?

有什么方法可以检查两个 clojure 实例是否指向相同的内存吗?

很抱歉我的错误术语,例如“指向”和“实例”,我是 Clojure 的新手,仍在学习它。 :-)

最佳答案

根据this question on google groups的回答它是按值传递的。

Clojure inherits the argument-passing semantics from Java. So it is pass-by-value, where the value passed is an object reference. In addition there are optimization facilities that enable the passing of primitive-typed values.

因此函数在传递参数时不会进行复制。 rdr您的代码中将是相同的实例。

由于 java 的互操作性,这样实现它是有意义的 - 否则你无法(轻松)用它的方法修改 java 对象的状态。

您可以轻松测试它:

(import 'java.util.HashMap)
(def m (new HashMap))
(defn foo [m] (defn bar [m] (.put m "testkey" "testvalue")) (bar m) (println (get m "testkey")))

(foo m)

结果:

testvalue
nil

如果bar创建了自己的 m 副本,然后 println不会打印 bar 内分配的值.

关于clojure - Clojure 中的参数传递是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18413575/

相关文章:

clojure - cljc 宏中的错误处理

design-patterns - 在 Clojure 的宏中声明设计模式

clojure - 从 Clojure 中的文件打印和阅读列表

java - 使用 JNA 在 Clojure 中按值获取和传递结构

clojure - 为什么更喜欢 seq 而不是非空作为谓词?

maven - Clojure REPL中的动态加载依赖项

clojure - 如何在 Clojure 宏的词法范围内捕获?

clojure - "Crossed"两个向量之间的和

Clojure - 是否可以在doseq语句中增加变量?

java - 在 clojure 中, (= 'a ' a) 指的是 'same atom' 吗?