有人可以帮助解释我们为什么会得到参数错误吗?我们不应该以这种方式检查真相吗?关于Elixir 1.3
iex(1)> true and true
true
iex(2)> "true"
"true"
iex(3)> true
true
iex(4)> true and "true"
"true"
iex(5)> "true" and true
** (ArgumentError) argument error: "true"
答案 0 :(得分:4)
Elixir有两组布尔运算符:
or
,and
和not
原则上要求他们的论点是实际的布尔值,即原子true
和false
||
,&&
和!
接受任何类型的参数,并检查"真实性"。虽然实际上or
和and
只检查第一个参数的类型。对于x
的任何值,表达式false or x
和true and x
将只返回x
。这可能看起来令人困惑,但它允许使用or
和and
作为递归函数中的最后一个表达式而不会妨碍尾递归。例如,考虑此函数,它检查列表中的所有元素是否等于42:
def x([]) do
true
end
def x([h|t]) do
h == 42 and x(t)
end
因为and
允许尾递归,所以此函数将在常量堆栈空间中运行。如果and
将检查其第二个参数的类型,则该函数必须正常调用一个堆栈帧"更深的",并在返回时执行检查并返回值。
答案 1 :(得分:2)
“罗嗦”布尔运算符 - and
,or
和not
是严格的 - 他们希望所有值都是严格的布尔值。符号运算符 - &&
,||
和!
- 对“真实性”而不是严格的布尔值进行操作。
因为所有布尔运算符都是短路的,所以实际上它们只会检查第一个参数是否是严格的布尔值,但我不鼓励将它们与非布尔值一起使用。
答案 2 :(得分:0)
来自文档:
Elixir还提供了三个布尔运算符:或者,而不是。这些 运算符是严格的,因为它们期望一个布尔值(true或 假)作为他们的第一个论点:
iex> true and true true iex> false or is_atom(:example) true
提供非布尔值会引发异常:
iex> 1 and true ** (ArgumentError) argument error: 1
这就是为什么要回答它的提升。
为了做你想做的事,你需要使用&&
运算符,所以它将是
"true" && true
再次,来自文档的引用:
除了这些布尔运算符,Elixir还提供了||,&&而且! 它接受任何类型的参数。对于这些运算符,所有值 除了false和nil将评估为true:
# and iex> nil && 13 nil iex> true && 17 17