首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何评估edn/read列表?

如何评估edn/read列表?
EN

Stack Overflow用户
提问于 2019-05-04 22:22:28
回答 2查看 376关注 0票数 0
代码语言:javascript
复制
(def a (edn/read-string "(+ 1 3)"))
; => (+ 1 3)

如何评估这个结果列表?

代码语言:javascript
复制
(type (first a))
; => cljs.core/Symbol

(= (first a) '+)
; => true

我想,更一般的情况下,我将如何从符号->函数。这是clojure的一种正常做法吗?我似乎在上面找不到任何东西。也许我没有找到正确的术语。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-05-04 22:52:20

我的答案似乎只适用于Clojure,而不适用于ClojureScript。见other answer

我想你可能在找resolve

代码语言:javascript
复制
(defn my-simple-eval [expr]
  ; Cut the function symbol from the arguments
  (let [[f & args] (edn/read-string expr)]
    ; Resolve f to a function then apply the supplied arguments to it 
    (apply (resolve f) args)))

(my-simple-eval "(+ 1 3)")
=> 4

不过,这些论点必须是空泛的数字,才能奏效。如果您想要允许子表达式,可以使它是递归的:

代码语言:javascript
复制
(defn my-simple-eval-rec [expr]
  (letfn [(rec [[f & args]]
            (->> args
                 (map (fn [arg]
                        (if (list? arg)
                          (rec arg) ; Process the sub-expr
                          arg)))

                 (apply (resolve f))))]

    (rec (edn/read-string expr))))

(my-simple-eval-rec "(+ 1 (+ 2 5))")
=> 8

如果这还不够的话,除了使用eval之外,我不知道其他任何方法

代码语言:javascript
复制
(def a (edn/read-string "(+ 1 3)"))

(eval a)
=> 4

或者,如果在展开宏时数据可用,则只需将对read-string的调用包装为将数据解释为正常:

代码语言:javascript
复制
(defmacro my-read-string [expr]
  (edn/read-string expr))

(my-read-string "(+ 1 3)")
=> 4
票数 2
EN

Stack Overflow用户

发布于 2019-05-05 22:44:46

你通常会使用eval。但是在ClojureScript中,您需要在运行时使用编译器和标准库。这只有在您使用自托管ClojureScript时才有可能。

如果您是在一个自我托管的环境中(如Lumo、Planck、will、Klipse等),那么eval将只工作:

代码语言:javascript
复制
cljs.user=> (require '[clojure.edn :as edn])
nil
cljs.user=> (def a (edn/read-string "(+ 1 3)"))
#'cljs.user/a
cljs.user=> (eval a)
4

否则,可以使用cljs.js命名空间中的工具访问自托管的ClojureScript:

代码语言:javascript
复制
cljs.user=> (require 'cljs.js)
nil
cljs.user=> (cljs.js/eval (cljs.js/empty-state)
  a {:eval cljs.js/js-eval :context :expr} prn)
{:value 4}

请注意,这样做会带来一些大小考虑: ClojureScript编译器将与您编译的工件一起带到目标环境中,您还必须避免使用:advanced,确保整个cljs.core标准库和相关元数据在运行时可用。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55987291

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档