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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-cloud-platform/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,我在执行一个宏进行Java互操作时遇到了一个空指针异常,我不知道为什么 我使用带有嵌套数据的映射设置Java对象的字段,由于映射键的名称与对象的字段名称相同,我创建了一个宏: (defmacro设置关键点![pose m k klst] `(集合!(.~pose~(symbol(name k))) (双数组(map#)((~(keyword(name k))~m))~klst))) 为了进行测试,我将pse定义为一个初始化的Java对象,将感兴趣的字段设置为零,并将mp定义为一个仍能工作的简化

我在执行一个宏进行Java互操作时遇到了一个空指针异常,我不知道为什么

我使用带有嵌套数据的映射设置Java对象的字段,由于映射键的名称与对象的字段名称相同,我创建了一个宏:

(defmacro设置关键点![pose m k klst]
`(集合!(.~pose~(symbol(name k)))
(双数组(map#)((~(keyword(name k))~m))~klst)))
为了进行测试,我将
pse
定义为一个初始化的Java对象,将感兴趣的字段设置为零,并将
mp
定义为一个仍能工作的简化映射:

(defmp{:pos{:x1:y2})
现在出现了奇怪的行为。使用显式键入的参数执行
设置键!

user>(设置键!pse mp:pos[:x:y])
#
但是,如果我在a
中使用运行代码,让
调用:

user>(让[x:posy[:x:y]]
(设置键!pse mp x y))
我得到一个空指针异常,消息为“No message”。这里有什么问题

编辑:我用
(def pse(pose_.)定义了
pse
pose_t
是一个生成的类,
pose_t()
构造函数初始化其字段中的所有数组,但不初始化值。简化示例中类代码的相关行为:

public-double-pos[];
公众姿势(){
pos=新双精度[3];
}

宏参数不求值,因此
~(关键字(名称k))
扩展为-大致-
(关键字(名称(引号x))
-即:x,而不是:pos

至少我想这是问题所在。如果不是,如果你能为
pse
添加一个定义就好了

附录:您可以通过评估以下内容来检查宏实际扩展到什么:

user> (macroexpand-1 '(set-keys! pse mp x y))
(set! (. pse x) (clojure.core/double-array (clojure.core/map
    (fn* [p1__2066__2067__auto__] (p1__2066__2067__auto__ (:x mp))) y)))
注:x


附录2:
(.obj字段)
实际上也不计算
字段
,这意味着您必须使用java反射来使字段参数动态。

您是对的,这就是问题所在。对于这一部分,我可以将
~(关键字(名称k))
更改为简单的
~k
,但是
~(符号(名称k))
扩展到
x
而不是
pos
。为什么unquote不强制
x
求值?是因为宏扩展发生在运行之前?如果是这样,我如何以编程方式将参数发送到宏?我最终必须使用
设置键对集合调用
map
对传递给map的函数进行de。是的,这是因为宏操作代码而不是值。unquote不求值,它插入文字表达式(代码段)这是作为参数给出的。据我所知,您可以使用普通函数和java反射或关键字到字段赋值函数的固定映射更清楚地编写所需的功能。也就是说,如果您确实需要动态传递值-如果您可以“静态”传递字段名,您已经有了一个有效的解决方案。