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/