"或"在Clojure工作?

时间:2015-12-27 06:38:59

标签: clojure

为什么第二个操作计算为false?是"还是"参数在clojure中的功能不同?如果是这样,我应该如何编写操作,以便无论0在参数中的哪个位置都计算为真?

(= (or 0 1) 0) ; true

(= (or 1 0) 0) ; false

5 个答案:

答案 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真值适用规则:nilfalse是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中nilfalse是假的,其他一切都是真的。

如果要在列表中存在零时表达式的结果为true,则应测试列表中的某些元素是否等于零。 (some zero? [0 1])

答案 4 :(得分:2)

您正在测试相等的逻辑值。这是大多数语言中的代码气味,在Clojure中更糟糕。

(or 0 1) ; 0
(or 1 0) ; 1

...因为01逻辑上都是真的,or返回其第一个逻辑真参数(或者最后一个参数,如果没有真参数)。唯一不正确的事情是nilfalse(及其框形式Boolean/FALSE)。

or是宏的事实在这种情况下是偶然的。