Spec-Zone.ru › Elixir 1.13

Операторы

В данном документе рассматриваются операторы в Elixir, как они парсятся, как их можно определить и как их можно переопределить.

Порядок приоритета и ассоциативность операторов

Ниже приведен список всех операторов, которые может обработать Elixir, упорядоченные по убыванию приоритета вместе с их ассоциативностью:

Оператор Ассоциативность
@ Унарная
. Левая
+ - ! ^ not ~~~ Унарная
** Левая
* / Левая
+ - Левая
++ -- +++ --- .. <> Правая
in not in Левая
|> <<< >>> <<~ ~>> <~ ~> <~> <|> Левая
< > <= >= Левая
== != =~ === !== Левая
&& &&& and Левая
|| ||| or Левая
= Правая
& Унарная
=> (действительно только внутри %{}) Правая
| Правая
:: Правая
when Правая
<- \\ Левая

Общие операторы

Elixir предоставляет следующие встроенные операторы, определенные как функции, которые можно переопределить:

  • + и - - унарный плюс/минус
  • +, -, * и / - основные арифметические операции
  • ++ и -- - конкатенация списков и вычитание
  • and и && - строгий и нестрогий логический оператор "и"
  • or и || - строгий и нестрогий логический оператор "или"
  • not и ! - строгий и нестрогий логический оператор "не"
  • in и not in - проверка на вхождение
  • @ - атрибут модуля
  • .. - создание диапазона
  • <> - конкатенация двоичных данных
  • |> - конвейер
  • =~ - сопоставление по тексту

Многие из них могут быть использованы в гвардах; обратитесь к списку разрешенных функций и операторов гвард.

Кроме того, есть несколько других операторов, которые Elixir парсит, но фактически не использует. См. Пользовательские и переопределенные операторы ниже для списка и рекомендаций по их использованию.

Некоторые другие операторы являются специальными формами и не могут быть переопределены:

  • ^ - оператор привязки
  • . - оператор точки
  • = - оператор сопоставления
  • & - оператор захвата
  • :: - оператор типа

Наконец, эти операторы появляются в таблице приоритета выше, но имеют смысл только в определенных конструкциях:

  • => - см. %{}
  • when - см. Гварды
  • <- - см. for и with
  • \\ - см. Значения по умолчанию

Операторы сравнения

Elixir предоставляет следующие встроенные операторы сравнения (все из которых могут быть использованы в гвардах):

  • == - равно
  • === - строго равно
  • != - не равно
  • !== - строго не равно
  • < - меньше
  • > - больше
  • <= - меньше или равно
  • >= - больше или равно

Единственное различие между == и === заключается в том, что === строго сравнивает целые числа и числа с плавающей точкой:

iex> 1 == 1.0
true
iex> 1 === 1.0
false

!= и !== являются отрицаниями == и === соответственно.

Порядок следования терминов

В Elixir разные типы данных могут быть сравнены с помощью операторов сравнения:

iex> 1 < :an_atom
true

Причина, по которой мы можем сравнивать разные типы данных, заключается в прагматизме. Алгоритмы сортировки не должны беспокоиться о разных типах данных для сортировки. Для справки, общий порядок сортировки определен ниже:

number < atom < reference < function < port < pid < tuple < map < list < bitstring

При сравнении двух чисел разных типов (число — это либо целое число, либо число с плавающей точкой) всегда происходит преобразование в тип с большей точностью, если оператор сравнения не является === или !==. Число с плавающей точкой считается более точным, чем целое число, за исключением случаев, когда число с плавающей точкой больше или меньше +/-9007199254740992.0 соответственно, в этом случае все значимые цифры числа с плавающей точкой будут слева от десятичной точки. Это сделано для того, чтобы сравнение больших чисел оставалось транзитивным.

Типы коллекций сравниваются по следующим правилам:

  • Кортежи сравниваются по размеру, а затем по элементам.
  • Карты сравниваются по размеру, затем по ключам в порядке возрастания термов, затем по значениям в порядке ключей. В частности, целые числа всегда считаются меньше чисел с плавающей точкой.
  • Списки сравниваются по элементам.
  • Битовые строки сравниваются байт за байтом, неполные байты сравниваются бит за битом.
  • Атомы сравниваются по своему строковому значению, по кодовому пункту.

Пользовательские и переопределенные операторы

Определение пользовательских операторов

Elixir может анализировать предопределенный набор операторов; это означает, что нельзя определять новые операторы (например, как это можно сделать в Haskell). Однако не все операторы, которые может проанализировать Elixir, используются Elixir: например, + и || используются Elixir для сложения и логического или, но <~> не используется (но допустим).

Для определения оператора можно использовать обычные def* конструкции (def, defp, defmacro, и так далее), но с синтаксисом, аналогичным тому, как используется оператор:

defmodule MyOperators do
  # We define ~> to return the maximum of the given two numbers,
  # and <~ to return the minimum.

  def a ~> b, do: max(a, b)
  def a <~ b, do: min(a, b)
end

Чтобы использовать новые операторы, необходимо импортировать модуль, который их определяет:

iex> import MyOperators
iex> 1 ~> 2
2
iex> 1 <~ 2
1

Ниже приведена таблица всех операторов, которые может проанализировать Elixir, но которые по умолчанию не используются:

  • |||
  • &&&
  • <<<
  • >>>
  • <<~
  • ~>>
  • <~
  • ~>
  • <~>
  • <|>
  • +++
  • ---
  • ~~~

Следующие операторы используются модулем Bitwise при импорте: &&&, <<<, >>>, |||, ~~~. Дополнительную информацию см. в документации по Bitwise.

Обратите внимание, что сообщество Elixir в целом не рекомендует использовать пользовательские операторы. Их сложно читать и ещё сложнее понимать, так как у них нет описательного имени, как у функций. Тем не менее, в некоторых специфических случаях или в пользовательских языках программирования (DSL) такие решения могут быть оправданы.

Также возможно заменить предопределённые операторы, такие как +, но это крайне не рекомендуется.

← Предыдущая страница Правила именования
Следующая страница → Шаблоны и охранные условия

© 2012 Plataformatec
Licensed under the Apache License, Version 2.0.
https://hexdocs.pm/elixir/1.13.4/operators.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API