为什么第二个操作计算为false?是"还是"参数在clojure中的功能不同?如果是这样,我应该如何编写操作,以便无论0在参数中的哪个位置都计算为真?
(= (or 0 1) 0) ; true
(= (or 1 0) 0) ; false
答案 0 :(得分:5)
(or)(or x)(or x & next)
- 从左到右分别评估表达式一个。
如果form返回逻辑 true 值,or
将返回该值并且不评估任何其他表达式,否则返回
最后一个表达式的值,如果最后一个表达式为nil
,则为falsy
(来源:Clojure documentation)。
在第一个语句(= (or 0 1) 0)
中,(或0 1)返回0
,因为它是逻辑true
(在clojure inly nil
中,false
是假的)然后与0
进行比较,结果为true
。
在第二个语句(= (or 1 0) 0)
中,它返回1
并将其与0
进行比较,并返回false,因为它们不相等。
答案 1 :(得分:3)
或返回第一个非假值或false。所以在你的例子中或将返回参数列表中的第一个数字,零或其他。
答案 2 :(得分:3)
or
不起作用 - 它是一个宏。它扩展为if
次调用,if
真值适用规则:nil
或false
是flasey,其他一切都是真实的 - 包括0
。< / p>
user=> (when 0 (println "true"))
true
nil
您的代码扩展为:
user=> (macroexpand '(or 1 0))
(let* [or__4238__auto__ 1] (if or__4238__auto__ or__4238__auto__ (clojure.core/or 0)))
简而言之,or
生成的代码返回第一个truthy参数 - 或者最后一个。
因此,如果您想知道,如果您的列表包含任何零,请使用更合适的内容:
user=> (some zero? [1 2 3])
nil
user=> (some zero? [1 2 0])
true
如果0
还有一个参数:
user=> (some #{0} [1 2 3])
nil
user=> (some #{0} [1 2 0])
0
答案 3 :(得分:3)
在Clojure中nil
和false
是假的,其他一切都是真的。
如果要在列表中存在零时表达式的结果为true,则应测试列表中的某些元素是否等于零。
(some zero? [0 1])
答案 4 :(得分:2)
您正在测试相等的逻辑值。这是大多数语言中的代码气味,在Clojure中更糟糕。
(or 0 1) ; 0
(or 1 0) ; 1
...因为0
和1
逻辑上都是真的,or
返回其第一个逻辑真参数(或者最后一个参数,如果没有真参数)。唯一不正确的事情是nil
和false
(及其框形式Boolean/FALSE
)。
or
是宏的事实在这种情况下是偶然的。