Clojure 字符串到符号的计算结果错误

标签 clojure

user=> ((symbol "or") true false)
false
user=> (or true false)
true

为什么第一个表单的计算结果为false?我想这两种输入形式是等效的。

奇怪的是,颠倒参数的顺序是有效的:

user=> ((symbol "or") false true)
true
user => (or false true)
true

最佳答案

当您评估列表(或 true false) 时,Clojure 首先评估第一项。在本例中,第一项是命名宏的符号,因此 Clojure 扩展宏并计算结果数据结构(在本例中为 let 形式)。

另一方面,当您评估列表((symbol "or") true false)时,Clojure 再次首先评估第一项,但在本例中,第一项是另一个列表! 列表的第一个元素是符号symbol,它命名一个函数,因此Clojure再次使用参数“or”调用该函数产生符号。换句话说,您基本上是在评估('或 true false)

这里有一个问题:Clojure 不会接受它刚刚评估的东西,然后再次评估它。相反,由于它首先不是一个符号,Clojure 会评估它,然后假设它一定是一个函数。它是一个函数吗?确实,答案是肯定的!

user> (ifn? 'do)
;=> true

这里有点棘手。 Symbol 类上 invoke 的实现与 Keyword 类上 invoke 的实现相同:假设第一个参数是一个映射,并尝试在该映射中查找自身。如果您提供第二个参数,它将使用它作为默认值。

现在,显然,如果您尝试将 true 视为 map 并在该 map 中查找符号 or,您将什么也找不到。因此,Clojure 会返回您提供的默认值:false。您可以在第二个参数位置放置任何您想要的值,只要您的符号不作为第一个参数中的键存在,您总是会取回默认值。

关于Clojure 字符串到符号的计算结果错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35541931/

相关文章:

ajax - 如何处理 cljs-ajax 响应?

在 Clojure 中对拉丁字符串进行排序

Clojure 交易策略

clojure - 如何在 Clojure 中创建本地类型?

emacs - 使用 Paredit 包装现有表达式

clojure - 如何检查 map 中是否存在嵌套键

scala - 如何访问 Scala REPL 中的最后结果?

clojure - 返回序列中的重复项

file - Clojure:等同于 Common Lisp READ 函数?

constructor - 使用 defrecord 构造函数调用 apply?