(布尔。假)在Clojure中

时间:2013-09-07 19:17:46

标签: clojure jvm boolean

根据http://hyperpolyglot.org/lisp,Clojure中唯一的谎言是falsenil。确实,令人惊讶的是,(Boolean. false)并非虚假:

user=> (if (Boolean. false) 1 2)
1
user=> (not (Boolean. false))
false
user=> (false? (Boolean. false))
false

另一方面,它以某种方式 false:

user=> (class false)
java.lang.Boolean
user=> (= false (Boolean. false))
true

这是违反直觉的。这种行为有原因还是被忽视了? Clojure中的其他Java数据类型是否也会发生类似的事情?它在ClojureScript和ClojureCLR中是否相同,或者它是否特定于JVM版本?其他JVM Lisps,如Kawa或ABCL,是否表现出类似的行为(如果他们使用Java布尔值)?

3 个答案:

答案 0 :(得分:12)

您可以在http://clojure.org/special_forms#if找到解释。

阅读整个段落是件好事,但这里的重点是摘录,重点是:

  

[...] Clojure中的所有条件都基于相同的逻辑,即 nil false 构成逻辑错误,以及所有内容否则构成逻辑真理,这些意义贯穿始终。 [...] 请注意 if 不测试java.lang.Boolean的任意值,只测试奇异值false(Java的Boolean.FALSE),因此,如果您要创建自己的盒装布尔值,请确保使用Boolean / valueOf而不是布尔构造函数。

比较

System.out.println(Boolean.valueOf(false) ? true : false);  // false
System.out.println(new Boolean(false)     ? true : false);  // false

user=> (if (Boolean/valueOf false) true false)
false
user=> (if (Boolean. false) true false)
true

因此,(Boolean. false)既不是nil也不是false,正如(Object.)既不是nil也不是false。正如@Chiron指出的那样,无论如何使用它都是不好的做法。

至于(= false (Boolean. false))是真的,我认为@ looby的解释是正确的:因为=依赖于Java的equals方法,Clojure中条件的特殊语义不适用,和布尔相等将与Java一样。

答案 1 :(得分:5)

不要永远调用(Boolean。true)或(Boolean。“true”)。不要创建任何布尔类的实例。这两种形式真的很邪恶。

这不是Clojure的问题,实际上它是Java的问题。

布尔值只有两个可能的值:true或false,它们已由Java提供。构造函数给你一种错觉,你可以创建一个布尔类的新实例,它可以表现为布尔但不会。

如果你真的想从String或boolean创建一个布尔实例,那么使用Boolean类的valueOf()方法。

(Boolean/valueOf "true")
(Boolean/valueOf  true)

Boolean.html#valueOf(boolean)

答案 2 :(得分:3)

我认为发生这种情况的原因是Clojure's =使用Java的equals方法。所以(= x y)就像x.equals(y)。因此,false在引擎盖下的比较中被强制导入(Boolean. false)

请注意,这并不意味着(Boolean. false) 为假与false 相同,只是在false(Boolean. false)使用equals方法对它们进行比较。