将可变方法映射到 Clojure 中的 Java 个对象
Mapping mutable methods onto Java objects in Clojure
使用 Clojure,假设 t
表示一个 Java 对象,而我有一个 [ts]
.
的集合
如何将 .setter
映射到 [ts]
?我在使用 (map #(.setter %1 %2) ts [vals])
时遇到问题。当我之后访问相关的 getter 时,我 return 一个 nil
s.
的列表
听起来 setter
方法没有 returning 修改后的 t
对象。如果你写了 setter
,你可以修改它,让它变成这样,或者你只需要坚持你原来的 ts
(但也要确保使用 dorun
来挤出map
的懒惰):
(let [ts ...]
(dorun (map #(.setter %1 %2) ts [vals]))
(println "Modified ts:" ts))
如果拥有 map
return 集合对您来说更方便,另一种方法是执行如下操作:
(dorun (map #(do (.setter %1 %2) %1) ts [vals]))
以ArrayList
Javaclass为例。我创建了其中三个,然后将 "s1" 添加到第一个,将 "s2" 添加到第二个,将 "s3" 添加到第三个。这是我的 "setter".
然后我读取每个的第一个值,我希望得到 "s1"、"s2"、"s3" - 所以在这个例子中是 getter。
(let [ts [(java.util.ArrayList. 1)
(java.util.ArrayList. 1)
(java.util.ArrayList. 1)]]
; Add one element to each of the ArrayList's
(doall (map #(.add %1 %2) ts ["s1" "s2" "s3"]))
; Verify that elements are indeed added.
(doall (map #(.get %1 0) ts)))
此示例按预期工作 - 后者 mapv
returns ("s1" "s2" "s3")
.
为什么类似的方法对您不起作用?好吧,我强烈怀疑那是因为你使用了 map
,其中 return 是一个惰性序列。
map
return 是一个惰性序列,这意味着除非您尝试 get/use 它产生的值,否则它不会计算 - 而且您通常不需要 return 来自 setter 的值。这意味着您的 setter 将永远不会被调用。
这就是我使用 doall
的原因 - 它需要一个惰性序列并实现它,这意味着每个元素都会被计算(在你的情况下 - 每个 setter 都会被调用)。
我的示例,当我在设置元素时仅使用 map
而不是 doall
时,将会失败:
(let [ts [(java.util.ArrayList. 1)
(java.util.ArrayList. 1)
(java.util.ArrayList. 1)]]
; Use a lazy map here - without doall
(map #(.add %1 %2) ts ["s1" "s2" "s3"])
(doall (map #(.get %1 0) ts)))
; java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
它确实失败了,因为没有添加任何元素。
或者,您可以使用 mapv
变体,它 return 是一个向量,因此总是不惰性的:
(let [ts [(java.util.ArrayList. 1)
(java.util.ArrayList. 1)
(java.util.ArrayList. 1)]]
; Use a lazy map, but realize sequence using doall
(doall (map #(.add %1 %2) ts ["s1" "s2" "s3"]))
(mapv #(.get %1 0) ts))
正如@John Wiseman 在评论中指出的那样,mapv
可能是一个更糟糕的选择,因为并不总是很清楚它用于强制实现,而 doall
则明确且显而易见。
关于惰性序列的一句话:
A lazy seq is a seq whose members aren't computed until you try to access them.
了解更多有关惰性序列的知识是一件好事,因为它们是 Clojure 代码库中广泛使用的强大工具。他们给 table 带来的一件有点违反直觉的事情是创建无限序列的能力,即 (range) 创建所有从 0 开始的数字的无限序列。所以这样做是完全合法的:
(map #(* % %) (range))
它将创建一个由所有数字组成的无限惰性平方序列!
使用 Clojure,假设 t
表示一个 Java 对象,而我有一个 [ts]
.
如何将 .setter
映射到 [ts]
?我在使用 (map #(.setter %1 %2) ts [vals])
时遇到问题。当我之后访问相关的 getter 时,我 return 一个 nil
s.
听起来 setter
方法没有 returning 修改后的 t
对象。如果你写了 setter
,你可以修改它,让它变成这样,或者你只需要坚持你原来的 ts
(但也要确保使用 dorun
来挤出map
的懒惰):
(let [ts ...]
(dorun (map #(.setter %1 %2) ts [vals]))
(println "Modified ts:" ts))
如果拥有 map
return 集合对您来说更方便,另一种方法是执行如下操作:
(dorun (map #(do (.setter %1 %2) %1) ts [vals]))
以ArrayList
Javaclass为例。我创建了其中三个,然后将 "s1" 添加到第一个,将 "s2" 添加到第二个,将 "s3" 添加到第三个。这是我的 "setter".
然后我读取每个的第一个值,我希望得到 "s1"、"s2"、"s3" - 所以在这个例子中是 getter。
(let [ts [(java.util.ArrayList. 1)
(java.util.ArrayList. 1)
(java.util.ArrayList. 1)]]
; Add one element to each of the ArrayList's
(doall (map #(.add %1 %2) ts ["s1" "s2" "s3"]))
; Verify that elements are indeed added.
(doall (map #(.get %1 0) ts)))
此示例按预期工作 - 后者 mapv
returns ("s1" "s2" "s3")
.
为什么类似的方法对您不起作用?好吧,我强烈怀疑那是因为你使用了 map
,其中 return 是一个惰性序列。
map
return 是一个惰性序列,这意味着除非您尝试 get/use 它产生的值,否则它不会计算 - 而且您通常不需要 return 来自 setter 的值。这意味着您的 setter 将永远不会被调用。
这就是我使用 doall
的原因 - 它需要一个惰性序列并实现它,这意味着每个元素都会被计算(在你的情况下 - 每个 setter 都会被调用)。
我的示例,当我在设置元素时仅使用 map
而不是 doall
时,将会失败:
(let [ts [(java.util.ArrayList. 1)
(java.util.ArrayList. 1)
(java.util.ArrayList. 1)]]
; Use a lazy map here - without doall
(map #(.add %1 %2) ts ["s1" "s2" "s3"])
(doall (map #(.get %1 0) ts)))
; java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
它确实失败了,因为没有添加任何元素。
或者,您可以使用 mapv
变体,它 return 是一个向量,因此总是不惰性的:
(let [ts [(java.util.ArrayList. 1)
(java.util.ArrayList. 1)
(java.util.ArrayList. 1)]]
; Use a lazy map, but realize sequence using doall
(doall (map #(.add %1 %2) ts ["s1" "s2" "s3"]))
(mapv #(.get %1 0) ts))
正如@John Wiseman 在评论中指出的那样,mapv
可能是一个更糟糕的选择,因为并不总是很清楚它用于强制实现,而 doall
则明确且显而易见。
关于惰性序列的一句话:
A lazy seq is a seq whose members aren't computed until you try to access them.
了解更多有关惰性序列的知识是一件好事,因为它们是 Clojure 代码库中广泛使用的强大工具。他们给 table 带来的一件有点违反直觉的事情是创建无限序列的能力,即 (range) 创建所有从 0 开始的数字的无限序列。所以这样做是完全合法的:
(map #(* % %) (range))
它将创建一个由所有数字组成的无限惰性平方序列!