在 clojure 中读取字符串和加载字符串有什么区别?



我有以下表格:

((read-string "+") 2 3)

返回3

我有两个问题:

1( 为什么上面的表单返回3而不是nil,或者抛出异常或其他任何东西?这个表单究竟是如何解析的?2( 在这种情况下,read-string返回了什么?它与我使用load-string有什么不同?

(read-string "+")返回一个符号+,该符号可以解析或求值以获得实际值,即+函数。

load-string返回表达式的结果。

换句话说,load-string等于(eval (read-string "+"))

你不会因为语言为你做评估而得到零或异常。

  1. 编译器解析符号+以计算表达式
  2. 根据当前的命名空间别名,+符号被解析为#'clojure.core/+,因为核心别名总是可用的。

    (class (read-string "+"))
    ; => clojure.lang.Symbol
    (class (resolve (read-string "+")))
    ; => clojure.lang.Var
    (class (deref (resolve (read-string "+"))))
    ; => clojure.core$_PLUS_`
    

您实际要做的是使用符号作为函数并向其传递参数;A更详细地介绍了这一点。从答案来看:

现在符号可以用作函数(它们实现clojure.lang.IFn接口(,但是在方式是他们在争论中审视自己,即对待他们的论点作为一个地图,并在里面进行查找

如@akond的回答所述,read-string返回一个符号,load-string也对其进行求值。您可以通过传递任何其他符号来触发相同的行为:

((symbol 'hi) 2 3)
;; 3
('foo 2 3)
;; 3
('foo '{foo 2} 3)
;; 2
('foo 2)
;; nil since there is no default value provided

如果您很好奇,可以看看Clojure源代码中的Symbol实现。

最新更新