(Boolean.false)在Clojure中
根据,Clojure中唯一的错误是(Boolean.false)在Clojure中,clojure,jvm,boolean,Clojure,Jvm,Boolean,根据,Clojure中唯一的错误是false和nil。事实上,令人惊讶的是,(Boolean.false)不是false: user=> (if (Boolean. false) 1 2) 1 user=> (not (Boolean. false)) false user=> (false? (Boolean. false)) false 另一方面,它在某种程度上是错误的: 这相当违反直觉。这种行为是有原因的还是被忽略了?永远不要调用(Boolean.true)或(Bool
false
和nil
。事实上,令人惊讶的是,(Boolean.false)
不是false:
user=> (if (Boolean. false) 1 2)
1
user=> (not (Boolean. false))
false
user=> (false? (Boolean. false))
false
另一方面,它在某种程度上是错误的:
这相当违反直觉。这种行为是有原因的还是被忽略了?永远不要调用(Boolean.true)或(Boolean.true)。不要创建布尔类的任何实例。这两种形式真的很邪恶
这不是Clojure的问题,实际上是Java的问题
布尔值只有两个可能的值:true或false,Java已经提供了这两个值。构造函数给你一种错觉,你可以创建一个布尔类的新实例,它可以表现为布尔类,但它不会
如果确实要从字符串或布尔值创建布尔实例,请使用布尔类的valueOf()方法
(Boolean/valueOf "true")
(Boolean/valueOf true)
我认为发生这种情况的原因是使用了Java的
equals
方法。所以(=xy)
就像x.equals(y)
。因此,false
在引擎盖下的比较中被强制为(Boolean.false)
请注意,这并不意味着
(Boolean.false)
为false或与false“相同”,只是当使用equals
方法比较false
和(Boolean.false)
时,它们被视为相等。您可以在中找到解释
阅读整段内容很好,但这里是摘录的关键部分,强调补充道:
[…]Clojure中的所有[…]条件句都基于相同的逻辑,即,nil和false构成逻辑虚假,其他一切构成逻辑真实,这些含义始终适用。[…]请注意,如果不测试java.lang.Boolean的任意值,则只测试单数值false(java的Boolean.false),因此如果要创建自己的装箱布尔值,请确保使用Boolean/valueOf,而不是Boolean构造函数
比较
System.out.println(Boolean.valueOf(false)?true:false);//假的
System.out.println(新布尔值(假)?真:假);//假的
与
因此,(Boolean.false)
既不是nil
也不是false
,正如(Object.)既不是nil
也不是false
。正如@Chiron所指出的,无论如何使用它都是不好的做法
至于(=false(Boolean.false))
是真的,我认为@looby的解释是正确的:因为=
依赖于Java的equals
方法,Clojure中条件的特殊语义不适用,布尔等式将与Java中的一样。正如本文其余部分所解释的,它们看起来会创建一个可用的布尔值,但实际上不会。这可能会导致奇怪的难以跟踪的bug。@Noises是的,这就是为什么没有人应该尝试通过调用构造函数来创建布尔实例的原因。谢谢你的回答。但我不太明白为什么这是Java的问题。我的意思是,在Java中,new Boolean(false)
在if子句中的行为正如人们所期望的那样(尽管我不认为它有什么用处)。
(Boolean/valueOf "true")
(Boolean/valueOf true)
user=> (if (Boolean/valueOf false) true false)
false
user=> (if (Boolean. false) true false)
true