Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Clojure 第一类/记录实例化_Clojure - Fatal编程技术网

Clojure 第一类/记录实例化

Clojure 第一类/记录实例化,clojure,Clojure,我有一个记录/类序列,我用new映射该序列,并期望得到这些记录/类的一系列实例。我知道new是一种特殊形式,但我希望Clojure在这种情况下做正确的事情 但这不起作用: (map new [SomeClass1 SomeClass2 SomeClass3]) 这也不是 (map #(new %) [SomeClass1 SomeClass2 SomeClass3]) 类似的代码在中工作 在Clojure这样做的正确方式是什么?(我希望它不会涉及Class.newInstance丑陋。) 编

我有一个记录/类序列,我用
new
映射该序列,并期望得到这些记录/类的一系列实例。我知道
new
是一种特殊形式,但我希望Clojure在这种情况下做正确的事情

但这不起作用:

(map new [SomeClass1 SomeClass2 SomeClass3])
这也不是

(map #(new %) [SomeClass1 SomeClass2 SomeClass3])
类似的代码在中工作

在Clojure这样做的正确方式是什么?(我希望它不会涉及
Class.newInstance
丑陋。)

编辑:

下面的方法可以工作,但可能比需要的慢。(我不确定。我希望能提供一些这方面的信息。)


我也在寻找更优雅的款式。

因为特殊的款式很适合。。。特别是,它们不是一流的,也不像适当的函数那样组合,您可以使用eval和宏来解决这一问题:

使用eval的解决方案:

(defn fnew [c] (eval `(new ~c))) 
hello.core> (map fnew ['Exception 'java.lang.String])
(#<Exception java.lang.Exception> "")
(defn fnew[c](eval`(new~c)))
hello.core>(映射fnew['Exception'java.lang.String])
(# "")
以及一个将参数传递给构造函数的版本:

(defn fnew [c] (eval `(new ~@c))) 

hello.core> (map fnew ['(Exception) '(java.lang.String "I am a contructor argument")])
(#<Exception java.lang.Exception> "I am a contructor argument")

(map fnew [ [Exception] [(class "foo") "I am a contructor argument"]])
(#<Exception java.lang.Exception> "I am a contructor argument")
(defn fnew[c](eval`(new~@c)))
hello.core>(映射fnew['(异常)'(java.lang.String“我是一个构造函数参数”))
(#“我是一个建设者论点”)
(映射fnew[[Exception][(类“foo”)“我是一个构造函数参数”]]
(#“我是一个建设者论点”)
这是一个宏观的例子

hello.core> (defmacro newify [classes] (apply vector (for [c classes] `(new ~c))))
#'hello.core/newify

hello.core> (macroexpand '(newify [java.lang.String Exception]))
[(new java.lang.String) (new Exception)]

hello.core>  (newify [java.lang.String Exception])
["" #<Exception java.lang.Exception>]
hello.core>(defmacro newify[classes](apply vector(用于[c类]`(new~c)))
#'hello.core/newify
hello.core>(macroexpand'(newify[java.lang.String异常])
[(新java.lang.String)(新异常)]
hello.core>(newify[java.lang.String异常])
["" #]

宏版本可能更高效,而eval版本更灵活

由于
new
是一种特殊形式,使其像第一类一样工作的解决方案之一是使用clojure低级调用,如:

(map #(clojure.lang.Reflector/invokeConstructor %1 (into-array [])) [String])

这可能会导致反射的性能问题,因此更倾向于基于宏的解决方案。

我希望将映射逻辑保留在外部。我问题的更广泛背景是以真正一流的方式处理类/记录实例化。旁注:当你编辑你的问题来添加新的内容时,新的文本应该放在原始文本的下面。或者至少使用
EDIT
标记使添加的内容变得明显。(在本例中,在我对问题进行
eval
编辑后,您添加了
eval
部分。)
hello.core> (defmacro newify [classes] (apply vector (for [c classes] `(new ~c))))
#'hello.core/newify

hello.core> (macroexpand '(newify [java.lang.String Exception]))
[(new java.lang.String) (new Exception)]

hello.core>  (newify [java.lang.String Exception])
["" #<Exception java.lang.Exception>]
(map #(clojure.lang.Reflector/invokeConstructor %1 (into-array [])) [String])