为什么if(not nil)给我ArgumentError?

时间:2018-12-03 10:55:11

标签: if-statement null boolean elixir

defmodule My do
  def go do
    x = nil

    if(not x) do
      IO.puts "hello"
    else
      IO.puts "goodbye"
    end
  end
end

在iex中:

/elixir_programs$ iex c.exs
Erlang/OTP 20 [erts-9.3] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false]

Interactive Elixir (1.6.6) - press Ctrl+C to exit (type h() ENTER for help)

iex(1)> My.go
** (ArgumentError) argument error
    c.exs:5: My.go/0

iex(1)> 

根据Programming Elixir >= 1.6,第35页:

  

Elixir具有与布尔运算有关的三个特殊值:true,   错误和无。在布尔上下文中将nil视为false。

似乎并非如此:

defmodule My do
  def go do
    x = false

    if (not x) do
      IO.puts "hello"
    else
      IO.puts "goodbye"
    end
  end
end

在iex中:

~/elixir_programs$ iex c.exs
Erlang/OTP 20 [erts-9.3] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false]

Interactive Elixir (1.6.6) - press Ctrl+C to exit (type h() ENTER for help)

iex(1)> My.go       
hello
:ok

iex(2)> 

2 个答案:

答案 0 :(得分:3)

  @spec not true :: false
  @spec not false :: true
  def not value do
    :erlang.not(value)
  end

Elixir对not函数的最新定义表明,它仅接收falsetrue

但是,nil不属于它们,因此显示argument error

  

Elixir具有与布尔运算有关的三个特殊值:true,false和nil。在布尔上下文中将nil视为false。

nil只是atom,即nil === :nil

您可以考虑使用!运算符,它实际上是Kernel.!宏。

  

接收任何自变量(不仅是布尔值),如果返回true,   参数为falsenil;否则返回false

!nil将返回true

答案 1 :(得分:0)

Kernel.not/1”或否/ 1期望布尔值

  

注意:nilfalse以外的其他值为true

尝试以下示例:

x = nil
if (x) do true else false end
false

带有short-if条件且值为true,false,nil的示例

iex> if nil , do: true, else: false
false
iex> if !nil , do: true, else: false
true
iex> if false , do: true, else: false
false
iex> if !false , do: true, else: false
true
iex> if not false , do: true, else: false
true
iex> if true , do: true, else: false
true
iex> if !true , do: true, else: false
false
iex> if not true , do: true, else: false
false