Почему номер ||логическое число? - PullRequest
1 голос
/ 13 мая 2019

Я новичок в Elixir, но не смог найти ответ на свой вопрос. Вот несколько примеров, которые я ввел для iex.

expression   result
9 || true    9
true || 9    true
9 && true    true
true && 9    9

Таким образом, при наличии || оно будет оцениваться как первый аргумент, а && - до последнего, когда один аргумент не является логическим. Как реализуются || и &&? Почему они возвращают эти результаты?

Ответы [ 3 ]

4 голосов
/ 13 мая 2019

Это обычная языковая возможность в контексте короткого замыкания логической логики. Выкинуть псевдокод из некоторых примеров, где это полезно:

need_a_number() && calculate_number() # do the expensive calculate_number() call, and evaluate to
                                      # its result, only if need_a_number() is truthy.

get_a_string() || "default string"  # returns "default_string" if get_a_string() is falsey

Если ваши && и || вернули только логические значения, вы не сможете выполнять как ветвление, так и вычисления в одной операции.

3 голосов
/ 14 мая 2019

Хотя ответ Чарльза верен, он не рассказывает всей истории. В целом Elixir имеет 2 разных набора операторов для работы с «булевыми» значениями:

  • && и || - это работает для всех типов, а буквально - это сокращения для:

    case left do # equivalent to left && right
      x when x in [nil, false] -> x
      _ -> right
    end
    
  • and и or, который работает только на true и false атомах и потерпит неудачу с BadBooleanError, когда будет предоставлено что-либо еще.

И, как уже было сказано, оба эти оператора имеют короткое замыкание, что означает, что они сократят вычисления, как только результат станет очевидным.

0 голосов
/ 14 мая 2019

Языки программирования реализуют концепцию истинных и ложных типов значений, чтобы использовать их в булевой логике . Некоторые значения считаются false , а другие считаются true при использовании в логических операциях и факте, что последнее значение функции - или выражение - возвращается, позволяет нам замыкать и разветвлять наши функции, как указано в предыдущем ответе.

Это верно для каждого языка, который я знаю.

В Elixir (1.7.3, скомпилированном с Erlang / OTP 21) я думаю, что у нас стабильное поведение, даже с нулевым числом:

(0 || false) == 0 # true
(0 || false) === 0 # true

И просто для сравнения, в Javascript (Google Chrome v74):

(0 || false) == 0 // true
(0 || false) === 0 // false
...