Чем nil, false и :false отличаются друг от друга?
В Elixir (и в языке Erlang, на котором он основан), значения nil, false и :false — это разные сущности, хотя могут казаться схожими, особенно для тех, кто пришёл из языков с нестрогой типизацией вроде JavaScript или Python. Каждый из этих элементов имеет собственный тип и поведение, особенно в условиях, проверках и логических операциях.
1. nil
-
Тип: Это атом, обозначающий "отсутствие значения" (:nil).
-
Тип данных в Elixir: atom()
-
Логическое поведение: В логическом контексте считается ложью, как и false.
-
Используется как: пустое значение, аналог null в других языках.
x = nil
is_nil(x) # true
x == nil # true
if x, do: "yes", else: "no" # "no"
-
nil часто возвращается:
-
если поиск не дал результата (например, в Map.get/3)
-
если переменная не инициализирована
-
при отсутствии значения у опционального аргумента функции
-
2. false
-
Тип: булев тип (boolean())
-
Значение: булево ложное значение, противоположность true
-
**Используется в логических операциях
**
x = false
is_boolean(x) # true
x == false # true
if x, do: "yes", else: "no" # "no"
- В логических выражениях участвует наряду с true. Используется как результат сравнений, проверок и булевой логики:
Enum.any?(\[\], fn x -> x > 0 end) # false
- Отличие от nil: false — логическая ложь, а nil — отсутствие значения, но оба интерпретируются как ложь в if, unless.
3. :false
-
Тип: атом с именем :false (аналог строкового значения 'false', но атомизированный)
-
НЕ является булевым значением! Это обычный атом, такой же как :ok, :error, :true, :ready, и т.п.
-
Логическое поведение: В отличие от false, **в логическом контексте считается истиной.
x = :false
is_atom(x) # true
x == false # false
if x, do: "yes", else: "no" # "yes"
- Может использоваться как тег состояния, флаг, ключ в мапе и т.д., но не как булев тип.
Сравнение по типам
Значение | Тип | Логическое значение | Комментарий |
---|---|---|---|
false | boolean() | Ложь | Логическое значение |
--- | --- | --- | --- |
nil | atom() | Ложь | Отсутствие значения |
--- | --- | --- | --- |
:false | atom() | Истина | Просто атом с именем false |
--- | --- | --- | --- |
Сравнение через == и ===
nil == false # false
nil == :false # false
false == :false # false
false === false # true
false === :false # false
Оператор === — строгий: сравнивает и тип, и значение. == — не строгий, но всё равно не приводит :false к false.
Использование в case, cond, if
if nil, do: "yes", else: "no" # "no"
if false, do: "yes", else: "no" # "no"
if :false, do: "yes", else: "no" # "yes"
Примеры практического отличия
def check_input(val) do
case val do
nil -> "Input is nil"
false -> "Input is false"
:false -> "Input is :false atom"
_ -> "Something else"
end
end
check_input(nil) # "Input is nil"
check_input(false) # "Input is false"
check_input(:false) # "Input is :false atom"
Заключение по сравнению (но без вывода, как просили)
-
false — булев тип, участвует в логике
-
nil — отсутствие значения, также ложь в логике
-
:false — обычный атом, может быть использован как метка, но не как false в логике
Это различие критично для правильной работы условных конструкций и сопоставления с образцом.