Spec-Zone.ru › Elixir 1.18

Исходный код Сигилы

Elixir предоставляет строковые значения в двойных кавычках, а также концепцию списков символов, которые определяются с помощью сигила синтаксиса ~c"hello world". В этой главе мы узнаем больше о сигилах и о том, как определить свои собственные.

Одной из целей Elixir является расширяемость: разработчики должны иметь возможность расширять язык, чтобы он соответствовал любому конкретному предметному области. Сигилы предоставляют основу для расширения языка с помощью пользовательских текстовых представлений. Сигилы начинаются с тильды (~) символа, за которым следует либо одна строчная буква, либо одна или несколько прописных букв, а затем разделитель. Дополнительные модификаторы добавляются после последнего разделителя.

Регулярные выражения

Наиболее распространенный сигил в Elixir — ~r, который используется для создания регулярных выражений:

# A regular expression that matches strings which contain "foo" or "bar":
iex> regex = ~r/foo|bar/
~r/foo|bar/
iex> "foo" =~ regex
true
iex> "bat" =~ regex
false

Elixir предоставляет совместимые с Perl регулярные выражения (regex), реализованные библиотекой PCRE. Regex также поддерживают модификаторы. Например, модификатор i делает регулярное выражение нечувствительным к регистру:

iex> "HELLO" =~ ~r/hello/
false
iex> "HELLO" =~ ~r/hello/i
true

Обратитесь к модулю Regex для получения дополнительной информации об остальных модификаторах и поддерживаемых операциях с регулярными выражениями.

Во всех примерах до сих пор использовался / для разграничения регулярного выражения. Однако сигилы поддерживают 8 различных разделителей:

~r/hello/
~r|hello|
~r"hello"
~r'hello'
~r(hello)
~r[hello]
~r{hello}
~r<hello>

Причина поддержки различных разделителей заключается в предоставлении способа записи литералов без экранированных разделителей. Например, регулярное выражение с косыми чертами, такое как ~r(^https?://), вероятно, читается лучше, чем ~r/^https?:\/\//. Аналогично, если регулярное выражение содержит косые черты и группы захвата (которые используют ()), вы можете выбрать двойные кавычки вместо скобок.

Сигилы строк, списков символов и списков слов

Помимо регулярных выражений, Elixir поставляется с тремя другими сигилами.

Строки

Сигил ~s используется для генерации строк, как и двойные кавычки. Сигил ~s полезен, когда строка содержит двойные кавычки:

iex> ~s(this is a string with "double" quotes, not 'single' ones)
"this is a string with \"double\" quotes, not 'single' ones"

Списки символов

Сигил ~c — это стандартный способ представления списков символов.

iex> [?c, ?a, ?t]
~c"cat"
iex> ~c(this is a char list containing "double quotes")
~c"this is a char list containing \"double quotes\""

Списки слов

Сигил ~w используется для генерации списков слов (слова — это просто обычные строки). Внутри сигила ~w слова разделены пробелами.

iex> ~w(foo bar bat)
["foo", "bar", "bat"]

Сигил ~w также принимает модификаторы c, s и a (для списков символов, строк и атомов соответственно), которые указывают тип данных элементов результирующего списка:

iex> ~w(foo bar bat)a
[:foo, :bar, :bat]

Интерполяция и экранирование в сигилах строк

Elixir поддерживает некоторые варианты сигилов для обработки экранирования символов и интерполяции. В частности, сигилы с прописными буквами не выполняют интерполяцию и экранирование. Например, хотя и ~s и ~S вернут строки, первый допускает коды экранирования и интерполяцию, а второй — нет:

iex> ~s(String with escape codes \x26 #{"inter" <> "polation"})
"String with escape codes & interpolation"
iex> ~S(String without escape codes \x26 without #{interpolation})
"String without escape codes \\x26 without \#{interpolation}"

Следующие коды экранирования можно использовать в строках и списках символов:

  • \\ — одиночная обратная косая черта
  • \a — звонок/сигнал
  • \b — возврат на одну позицию назад
  • \d — удаление
  • \e — escape
  • \f — подача формы
  • \n — перевод строки
  • \r — возврат каретки
  • \s — пробел
  • \t — табуляция
  • \v — вертикальная табуляция
  • \0 — нулевой байт
  • \xDD — представляет один байт в шестнадцатеричном формате (например, \x13)
  • \uDDDD и \u{D...} — представляют кодовую точку Юникода в шестнадцатеричном формате (например, \u{1F600})

В дополнение к этим кодам, двойная кавычка внутри строки в двойных кавычках должна быть экранирована как \", а, аналогично, одиночная кавычка внутри списка символов в одинарных кавычках должна быть экранирована как \'. Тем не менее, лучше стиль — изменить разделители, как показано выше, чем экранировать их.

Сигилы также поддерживают heredocs, то есть три двойных или одинарных кавычки в качестве разделителей:

iex> ~s"""
...> this is
...> a heredoc string
...> """

Наиболее распространенный случай использования сигилов heredoc — это написание документации. Например, запись символов экранирования в документации быстро станет проблематичной из-за необходимости двойного экранирования некоторых символов:

@doc """
Converts double-quotes to single-quotes.

## Examples

    iex> convert("\\\"foo\\\"")
    "'foo'"

"""
def convert(...)

Используя ~S, эту проблему можно полностью избежать:

@doc ~S"""
Converts double-quotes to single-quotes.

## Examples

    iex> convert("\"foo\"")
    "'foo'"

"""
def convert(...)

Сигилы календаря

Elixir предлагает несколько сигилов для работы с различными форматами времени и дат.

Дата

Структура %Date{} содержит поля year, month, day, и calendar. Вы можете создать её, используя сигил ~D.

iex> d = ~D[2019-10-31]
~D[2019-10-31]
iex> d.day
31

Время

Структура %Time{} содержит поля hour, minute, second, microsecond, и calendar. Вы можете создать её, используя сигил ~T.

iex> t = ~T[23:00:07.0]
~T[23:00:07.0]
iex> t.second
7

NaiveDateTime

Структура %NaiveDateTime{} содержит поля из Date и Time. Вы можете создать её, используя сигил ~N.

iex> ndt = ~N[2019-10-31 23:00:07]
~N[2019-10-31 23:00:07]

Почему она называется naive? Потому что она не содержит информации о часовом поясе. Следовательно, указанная дата и время может вообще не существовать или может существовать дважды в определённых часовых поясах — например, при переходе на летнее/зимнее время.

UTC DateTime

Структура %DateTime{} содержит те же поля, что и NaiveDateTime, с добавлением полей для отслеживания часовых поясов. Сигил ~U позволяет разработчикам создавать DateTime в часовом поясе UTC:

iex> dt = ~U[2019-10-31 19:59:03Z]
~U[2019-10-31 19:59:03Z]
iex> %DateTime{minute: minute, time_zone: time_zone} = dt
~U[2019-10-31 19:59:03Z]
iex> minute
59
iex> time_zone
"Etc/UTC"

Пользовательские сигилы

Как упоминалось в начале этой главы, сигилы в Elixir расширяемы. Фактически, использование сигила ~r/foo/i эквивалентно вызову sigil_r с двоичным и списком символов в качестве аргумента:

iex> sigil_r(<<"foo">>, [?i])
~r"foo"i

Мы можем получить доступ к документации для сигила ~r с помощью sigil_r:

iex> h sigil_r
...

Мы также можем предоставить свои собственные сигилы, реализовав функции, которые следуют шаблону sigil_{character}. Например, давайте реализуем сигил ~i, который возвращает целое число (с необязательным модификатором n для создания отрицательного числа):

iex> defmodule MySigils do
...>   def sigil_i(string, []), do: String.to_integer(string)
...>   def sigil_i(string, [?n]), do: -String.to_integer(string)
...> end
iex> import MySigils
iex> ~i(13)
13
iex> ~i(42)n
-42

Пользовательские сигилы могут быть либо одной строчной буквой, либо одной прописной буквой, за которой следуют другие прописные буквы и цифры.

Сигилы также могут использоваться для выполнения работы на этапе компиляции с помощью макросов. Например, регулярные выражения в Elixir компилируются в эффективное представление во время компиляции исходного кода, тем самым пропуская эту стадию во время выполнения. Если вас интересует эта тема, вы можете узнать больше о макросах и посмотреть, как реализованы сигилы в модуле Kernel (где определены функции sigil_*).

← Предыдущая страница Понимания
Следующая страница → try, catch и rescue

Скачать версию ePub

Создано с помощью ExDoc (v0.36.1) для языка программирования Elixir

© 2012-2024 The Elixir Team
Licensed under the Apache License, Version 2.0.
https://hexdocs.pm/elixir/1.18.1/sigils.html

Spec-Zone.ru

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