我在執行一個宏來執行一些Java互操作時收到一個空指針異常,但我找不出原因。使用Clojure宏中的綁定的空指針異常
我使用嵌套數據的地圖設置一個Java對象的字段,並且因爲地圖鍵的名稱是一樣的對象的字段名,我創建了一個宏:
(defmacro set-keys! [pose m k klst]
`(set! (. ~pose ~(symbol (name k)))
(double-array (map #(% (~(keyword (name k)) ~m)) ~klst))))
爲了測試,我定義pse
要與設置的關注爲零領域中的一個初始化的Java對象,我定義爲mp
的簡化圖,將仍起作用:
(def mp {:pos {:x 1 :y 2})
現在到了奇怪的行爲。用顯式類型的參數執行set-keys!
工作:
user> (set-keys! pse mp :pos [:x :y])
#<double[] [[email protected]>
但是,如果使用運行的代碼在一個let
調用內部:
user> (let [x :pos y [:x :y]]
(set-keys! pse mp x y))
我得到一個空指針異常與「沒有消息。」作爲消息。這裏有什麼問題?
編輯:我與(def pse (pose_t.))
定義pse
,pose_t
是生成的類,並且pose_t()
構造函數初始化所有陣列在其字段中,但不進行初始化的值。的類代碼爲簡化示例的相關行是:
public double pos[];
public pose_t() {
pos = new double[3];
}
你說得對,就是這個問題。對於那部分我可以把'〜(關鍵字(名字k))'改爲'〜k',但是我會用'〜(symbol(name k))'擴展爲'x' 'pos'。爲什麼不能用unquote force'x'來評估?是因爲宏擴展發生在運行時?如果是這樣,我怎樣才能以編程方式將參數發送給宏?我最終將不得不在傳遞給map的函數內使用'set-keys!'在集合上調用'map'。 – troyastorino
是的,這是因爲宏操作* code * - 不是值。 unquote不計算,它插入作爲參數給出的文字表達式(一段代碼)。據我所知,使用普通函數和java反射或關鍵字到字段賦值函數的固定映射,可以更清晰地編寫所需的功能。也就是說,如果您確實需要動態傳遞值 - 如果您可以「靜態」傳遞字段名稱,那麼您已經有了一個可行的解決方案。 –