9

我知道在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 绑定创建的同一个 rdr?

有没有办法检查两个 clojure 实例是否指向相同的内存?

很抱歉我的“指向”和“实例”等不好的术语,我是 Clojure 的新手,还在学习它。:-)

4

2 回答 2

7

根据对谷歌群组这个问题的回答,它是按价值传递的。

Clojure 继承了 Java 的参数传递语义。所以它是按值传递,其中传递的值是对象引用。此外,还有一些优化工具可以传递原始类型的值。

因此,函数在传递参数时不会进行复制。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

于 2013-08-24T01:05:38.747 回答
6

Clojure 就像 Java 一样是按值传递的。我认为它是按值传递的引用。Clojure 像这样工作并不是一件容易的事,Scheme 和 Common Lisp 的行为方式相同。

您可以使用以下命令测试两个引用是否指向同一内存identical?

(相同?xy)

测试 2 个参数是否是同一个对象

于 2013-08-24T01:25:40.540 回答