2013-06-23 85 views
2

讀串是否有使用與函數值讀取器,例如一種方法:Clojure的:上的功能

(讀 - 串(PR-STR +))

的RuntimeException不可讀形式的Clojure。 lang.Util.runtimeException (Util.java:219)

+0

你能詳細說明你正在努力完成什麼嗎? – user100464

+0

我需要將任意函數的名稱作爲字符串傳輸,然後將其讀回並應用該函數。 –

+0

只是函數的名字?換句話說,你可以假設雙方已經知道函數的定義了嗎? – user100464

回答

3

正如你可能已經知道(pr-str +)的輸出是無效的Clojure代碼,讀者可以解析:"#<core$_PLUS_ [email protected]>"。在使用函數pr,prn,println等功能時,函數值的輸出故意纏繞在#<閱讀器宏周圍,該宏被髮送到UnreadableReader,這是throws例外情況。

爲您提供可以使用print-dup功能,對於基本的序列化工作的例子:

(defn string-fn [f] 
    (let [w (java.io.StringWriter.)] 
    (print-dup f w) 
    (str w))) 

(let [plus (read-string (string-fn +))] 
    (plus 1 2)) 

+功能進行序列化實際上正在生成調用類的構造函數:

#=(clojure.core$_PLUS_.) 

當然,如果這個類已經在Clojure環境中編譯了,那麼你只能讀取這個字符串。如果您在運行新的REPL會話時序列化了一個匿名函數,將其保存到一個文件然後再讀回,它很可能不起作用,因爲每個匿名函數的類名是不同的並且取決於Clojure內部。

對於任意函數,事情會變得複雜得多。共享源代碼可能還不夠,該功能可能依賴於只存在於源環境中的任何其他函數或變量的使用。如果這是您正在考慮的操作,也許考慮其他方法來解決您正在嘗試解決的問題,則無需序列化任意函數的值。

希望它能幫助,

0

如果你只需要名字,你能不能只發送符號與(名稱「+)。

但是一般來說,使用clojure讀取,如果你想讀回來是一個壞主意,因爲clojure的讀者可能會在過程中執行一些代碼。也許看看edn reader:clojure.edn/read-string

但是,也許你只是需要將字符串轉換回符號,在這種情況下(符號名稱)函數就足夠了。