我正在尝试使用java interop来创建对象列表。
我尝试了for
和doseq
,但他们都遇到了问题。
for
是懒惰的,我需要创建所有对象,因为它们在内部互相交互。
(def master-object (MasterObject.))
(for [x [1 10 50 99]]
(let [child (.createChildObject master-object)]
(.setCoefficient child x)
child))
doseq
创建所有内容,但不返回列表。
(doseq [x [1 10 50 99]]
(let [child (.createChildObject master-object)]
(.setCoefficient child x)
child))
我在考虑使用loop
和recur
,但是想知道是否可以采用更惯用的方式。
由于
答案 0 :(得分:2)
如果你需要创建所有对象,那么我认为返回向量而不是列表是惯用的,例如:
(vec (for [x (range 3)]
x))
有几种不同的方法可以强制for
的所有输出。以上就是其中之一。 vec
只是into []
的缩写。因此,如果您确实需要一个已实现的列表,则可以改为:
(into '() (for [x (range 3)]
x))
用于创建对象列表doseq
对您没有帮助,因为它只是关于'副作用'。
您真的可以使用map
来完成您想要完成的任务。创建一个单独的映射函数并映射它:
(defn make-child [x]
(let [child (.createChildObject master-object)]
(.setCoefficient child x)
child))
(map make-child [1 10 50 99])
答案 1 :(得分:0)
实现延迟序列的神奇词是doall
。如果你将它包裹在var request = $.ajax({
type: 'GET',
url: url,
dataType: 'json',
xhrFields: {
withCredentials: true
}});
周围,你将得到你想要的效果:
for
请注意,返回的对象是(doall
(for [x [1 10 50 99]]
(let [child (.createChildObject master-object)]
(.setCoefficient child x)
child)))
=>
(#object[interop.core.ChildObject 0x326037f1 "interop.core.ChildObject@326037f1"]
#object[interop.core.ChildObject 0x759b711 "interop.core.ChildObject@759b711"]
#object[interop.core.ChildObject 0x2bc06dcb "interop.core.ChildObject@2bc06dcb"]
#object[interop.core.ChildObject 0x4a37a35a "interop.core.ChildObject@4a37a35a"])
,而不是列表。无论如何,REPL迫使其实现。
如果LazySeq
返回Java setCoefficient
,则可以将上述内容缩写为
this
你的代码结构让我很担心。你正在实现(doall
(for [x [1 10 50 99]]
(.. master-object
(createChildObject)
(setCoefficient x))))
和MasterObject
之间关联的一半 - 一个孩子知道它的主人;但不是另一半 - 主人不知道它的孩子。我们没有看到您对生成的子集合执行任何操作。如果是这样的话,没有任何东西可以引用它们,并且它们是垃圾,随时都会被处理掉。
我认为ChildObject
应保留其子集合,并在MasterObject
中创建ChildObject
时添加。然后,您无需保留已创建子项的集合,createChildObject
将优先于doseq
。我完全在Clojure interop中完成了如下操作:
for
这仍然非常难看,因为我还没有弄清楚如何抑制Java对象的默认呈现:
(ns interop.core)
(definterface ChildInterface
(setCoefficient [x]))
(definterface MasterInterface
(createChildObject [])
(getChildren []))
(deftype ChildObject [master ^:unsynchronized-mutable coefficient]
Object
(toString [this]
(str "Child " coefficient))
ChildInterface
(setCoefficient [this x]
(set! coefficient x)
this))
(deftype MasterObject [^:unsynchronized-mutable children]
Object
(toString [this]
(str "Master children: " (.seq children)))
MasterInterface
(createChildObject [this]
(let [child (ChildObject. this nil)]
(set! children (conj children child))
child))
(getChildren [this]
children))
(def master-object (MasterObject. []))
(doseq [x [1 10 50 99]]
(.. master-object
(createChildObject)
(setCoefficient x)))
我为孩子们使用了Clojure矢量。在这种情况下,Java集合也可以。