Elixir似乎每个操作都有2个布尔运算符:
|| , or && , and
唯一的区别是,对于or, and
etc,第一个参数本身必须是一个布尔值.这些第二组操作符有什么意义,|| , &&
等等似乎能够处理所有事情?
根据Elixir 基本操作员教程:
or
并且and
是短路运营商.如果左侧不足以确定结果,它们仅执行右侧
为了回答你的问题,第二组运营商有什么意义?; 我认为教程非常好.
根据经验,使用规则
and
,or
并且not
当你期待布尔值.如果任何参数为非布尔值,使用&&
,||
和!
.
我的看法
对我而言,这似乎是语言本身的最佳实践.
内联让它失败的哲学,在比较情况下对类型更严格可能是一个好主意.在iex(5)中,结果抛出ArgumentError.抛出这样的错误可能比错误地评估某些东西更好.
&&
和and
例子
iex(1)> nil && 13 nil iex(2)> true && 17 17 iex(3)> true and true true iex(4)> false and true false iex(5)> 73 and false ** (ArgumentError) argument error: 73
好吧,直接来自Elixir所有事物的真相来源:
两个主要原因:
编写断言代码:如果您期望使用布尔值,请使用布尔值
卫兵是严格的布尔,所以你必须在那里使用"和"和"或"
这是直接来自何塞瓦利姆.
另外,彼得·汉密尔顿(信用证到期的信用证)指出了Erlang的创造者之一Robert Virding的这一启发性信息:
关于布尔运算符和守卫的一些历史和一些哲学.
很久以前我们明确地决定让布尔运算符'和','或','xor'和'not'并且没有truthy值.这不是因为我们不熟悉truthy逻辑,我们是长期的C和lisp程序员,我们只觉得它更合乎逻辑(哈哈).这些最初都是严格的,只接受布尔参数.后来出现了短路'和'和'或'的愿望.我们没有重新定义'和'和'或',而是添加了新的运营商'andsoso'和'orelse'.最初这些是andalso(bool,bool)和orelse(bool,bool),因此将测试第二个参数的值.稍后会对此进行更改,以便不检查第二个参数,原因之一是这是其他语言的原因以及尾部调用优化的可能性.我个人从未使用过这个.
我个人不是真正的运营商的粉丝,并认为'nil'在其他语言中闻起来有点像null.
关于警卫.最初他们是守卫测试,并认为模式匹配的扩展与那些不能很好地写成模式的东西相匹配.测试成功或失败.IMAO使得警卫更加一致,并处理失败/异常,这只是一次失败的测试.当允许的守卫变得复杂时,他们徘徊成为保护表达式,它返回布尔值,然后整个守卫成为一个布尔表达式.我认为,这更难以解释为什么警卫的外表和行为与他们一样.
我将此答案标记为社区维基,因为它本身并不是我的答案.
对于我来说,当你不想将任何其他值(或数据类型)解释为true时,想要将布尔值作为第一个参数可能会有所帮助,因为除了nil和false之外,elixir将采用任何真值.用户可能希望确保参数是布尔值(true或false),而不是意外地除了任何其他类型的值.
布尔运算符像或者,和,没有想到真或假作为他们的第一个参数
像||这样的宽松布尔运算符 ,&& , ! 可以接受任何类型的参数.除nil或false之外的任何值都被解释为true(真实).
例如
x || y # gives x if x is truthy else y x && y # gives y if x is truthy else x !x # false if x is truthy , otherwise true
如果你试试
iex(5)> not 3 ** (ArgumentError) argument error :erlang.not(3) iex(6)> ! 3 false