【问题标题】:Elixir - Argument errorElixir - 参数错误
【发布时间】:2023-03-24 02:08:01
【问题描述】:

有人可以帮忙解释为什么我们得到参数错误吗?我们不应该以这种方式检查真实性吗?在 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"

【问题讨论】:

    标签: elixir


    【解决方案1】:

    Elixir 有两组布尔运算符:

    • orandnot 原则上要求它们的参数是实际的布尔值,即原子 truefalse
    • ||&&! 接受任何类型的参数,并检查“真实性”。

    虽然实际上orand 只检查first 参数的类型。对于x 的任何值,表达式false or xtrue and x 将简单地返回x。这可能看起来令人困惑,但它允许使用 orand 作为递归函数中的最后一个表达式,而不会妨碍尾递归。例如,考虑这个函数,它检查列表中的所有元素是否都等于 42:

    def x([]) do
      true
    end
    def x([h|t]) do
      h == 42 and x(t)
    end
    

    因为and 允许尾递归,所以该函数将在恒定堆栈空间中运行。如果and 将检查其第二个参数的类型,则该函数必须进行正常调用一个“更深”的堆栈帧,并在返回时执行检查并返回值。

    【讨论】:

    • 感谢您不仅解释了原因,还解释了其背后的基本原理
    【解决方案2】:

    “冗长”的布尔运算符 - andornot 是严格的 - 他们希望所有值都是严格的布尔值。符号运算符 - &&||! - 对“真实性”而不是严格的布尔值进行操作。

    因为所有布尔运算符都是短路的,它们实际上只会检查第一个参数是否为严格布尔值,但我不鼓励将它们与非布尔值一起使用。

    【讨论】:

      【解决方案3】:

      来自文档:

      Elixir 还提供了三个布尔运算符:or、and 和 not。这些 运算符是严格的,因为他们期望一个布尔值(真或 false) 作为他们的第一个论点:

      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
      

      【讨论】:

        猜你喜欢
        • 2021-02-14
        • 1970-01-01
        • 1970-01-01
        • 2015-02-14
        • 2018-03-13
        • 1970-01-01
        • 1970-01-01
        • 2017-12-26
        • 2017-12-26
        相关资源
        最近更新 更多