简体   繁体   English

“或”在Clojure中如何运作?

[英]How does “or” work in Clojure?

Why does the second operation computes to false? 为什么第二个操作计算为false? Does the "or" argument function differently in clojure? “或”参数在clojure中的功能是否有所不同? If so, how should I write the operation so it computes to true regardless of where the 0 is in the argument? 如果是这样,我应该如何编写操作,以便无论0在参数中的哪个位置,它都会计算为真?

(= (or 0 1) 0) ; true

(= (or 1 0) 0) ; false

(or)(or x)(or x & next) - evaluates expressions one at a time, from left to right . (or)(or x)(or x & next) - 从左到右一次评估一个表达式。

If form returns logical true value, or returns that value and doesn't evaluate any of the other expressions, otherwise it returns the value of the last expression or nil if last expression are falsy (Source: Clojure documentation ). 如果form返回逻辑true值, or返回该值并且不评估任何其他表达式,否则返回最后一个表达式的值,如果最后一个表达式为falsy ,则返回nil (来源: Clojure文档 )。

In first statement (= (or 0 1) 0) the (or 0 1) return 0 because it's is logical true ( in clojure inly nil and false are falsy) then compare with 0 so result is true . 在第一个语句(= (or 0 1) 0) ,(或0 1)返回0因为它是逻辑true (在clojure inly nilfalse是falsy)然后与0比较,因此result为true

In second statement (= (or 1 0) 0) it returns 1 and compare it to 0 and returns false because they aren't equal. 在第二个语句(= (or 1 0) 0)它返回1并将其与0进行比较并返回false,因为它们不相等。

or returns the first non-false value or false. 或返回第一个非假值或false。 So in your examples or will return the first number in the argument list, zero or otherwise. 所以在你的例子中或将返回参数列表中的第一个数字,零或其他。

or is no function - it is a macro. or没有功能 - 它是一个宏。 it expands to if calls and by that the rules of if truth apply: nil or false are flasey, everything else is truthy - including 0 . 它扩展到if调用,并且if真理适用的规则: nilfalse是flasey,其他一切都是真实的 - 包括0

user=> (when 0 (println "true"))
true
nil

Your code expands to: 您的代码扩展为:

user=> (macroexpand '(or 1 0))
(let* [or__4238__auto__ 1] (if or__4238__auto__ or__4238__auto__ (clojure.core/or 0)))

So in short, or 's generated code returns the first truthy argument -- or the last one. 所以简而言之, or生成的代码返回第一个truthy参数 - 或者最后一个。

So if you want to know, if your list there contains any zero use something more appropriate: 所以如果你想知道,如果你的列表包含任何零,请使用更合适的东西:

user=> (some zero? [1 2 3])
nil
user=> (some zero? [1 2 0])
true

Or in case the 0 there is a param too: 或者如果0也有一个参数:

user=> (some #{0} [1 2 3])
nil
user=> (some #{0} [1 2 0])
0

In Clojure nil and false are falsy, everything else is truthy. 在Clojure中, nilfalse都是假的, 其他一切都是真的。

If you want the result of the expression to be true when there is a zero in a list, you should test if some elements of the list are equal to zero. 如果希望在列表中存在零时表达式的结果为true,则应测试列表中的某些元素是否等于零。 (some zero? [0 1])

You are testing logical values for equality. 您正在测试相等的逻辑值。 This is a code smell in most languages and worse in Clojure. 这是大多数语言中的代码气味,在Clojure中更糟糕。

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

... since both 0 and 1 are logically true, and or returns its first logically true argument (or the last argument, if there is no true one). ...因为01在逻辑上都是真的,并且or返回它的第一个逻辑真参数(或者如果没有真参数则返回最后一个参数)。 The only things that aren't true are nil and false (and its boxed form Boolean/FALSE ). 唯一不正确的是nilfalse (以及它的盒装形式Boolean/FALSE )。

The fact that or is a macro is incidental in this case. 在这种情况下, or宏是偶然的事实。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM