Учебники

Эрланг — Краткое руководство

Эрланг — Обзор

Erlang — это функциональный язык программирования, который также имеет среду выполнения. Он был построен таким образом, чтобы в него была интегрирована поддержка параллелизма, распределения и отказоустойчивости. Erlang был изначально разработан для использования в нескольких крупных телекоммуникационных системах от Ericsson.

Первая версия Erlang была разработана Джо Армстронгом, Робертом Вирдингом и Майком Уильямсом в 1986 году. Изначально это был проприетарный язык в Ericsson. Позднее он был выпущен как язык с открытым исходным кодом в 1998 году. Erlang, наряду с OTP, набором промежуточного программного обеспечения и библиотек в Erlang, теперь поддерживается и поддерживается подразделением OTP в Ericsson и широко называется Erlang / OTP .

Почему Эрланг?

Erlang следует использовать для разработки вашего приложения, если у вас есть следующие требования —

  • Приложение должно обрабатывать большое количество одновременных действий.

  • Он должен легко распространяться по сети компьютеров.

  • Должна быть возможность сделать приложение отказоустойчивым как к программным, так и к аппаратным ошибкам.

  • Приложение должно быть масштабируемым. Это означает, что он должен иметь возможность охватывать несколько серверов практически без изменений.

  • Он должен легко обновляться и настраиваться без остановки и перезапуска самого приложения.

  • Приложение должно реагировать на запросы пользователей в определенные строгие сроки.

Приложение должно обрабатывать большое количество одновременных действий.

Он должен легко распространяться по сети компьютеров.

Должна быть возможность сделать приложение отказоустойчивым как к программным, так и к аппаратным ошибкам.

Приложение должно быть масштабируемым. Это означает, что он должен иметь возможность охватывать несколько серверов практически без изменений.

Он должен легко обновляться и настраиваться без остановки и перезапуска самого приложения.

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

Официальный сайт Erlang — https://www.erlang.org/ .

Erlang Официальный сайт

Эрланг — Окружающая среда

Теперь, прежде чем вы сможете начать работать с Erlang, вам необходимо убедиться, что в вашей системе работает полнофункциональная версия Erlang. В этом разделе мы рассмотрим установку Erlang и его последующую настройку на машине с Windows, чтобы начать работу с Erlang.

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

Системные Требования

объем памяти 2 ГБ ОЗУ (рекомендуется)
Дисковое пространство Нет минимальных требований. Желательно иметь достаточно места для хранения приложений, которые будут созданы с использованием Erlang.
Версия операционной системы Erlang может быть установлен на Windows, Ubuntu / Debian, Mac OS X.

Скачивание Эрланга

Чтобы скачать Erlang, нужно перейти по следующему адресу — www.erlang.org/downloads .

Эта страница имеет различные загрузки, а также шаги, необходимые для загрузки и установки языка на платформах Linux и Mac.

Эрланг Скачать

Нажмите на «OTP 18.3 Windows 32-bit Binary File», чтобы начать загрузку установочного файла Erlang Windows.

Erlang Установка

Следующие шаги подробно описывают, как Erlang может быть установлен в Windows —

Шаг 1 — Запустите установщик, загруженный в предыдущем разделе. После запуска установщика нажмите «Выполнить».

Erlang Установка

Шаг 2 — Нажмите Далее на следующем экране, чтобы принять компоненты по умолчанию, которые будут установлены.

Выберите компоненты

Шаг 3 — Примите путь установки по умолчанию и нажмите Далее.

Путь установки

Шаг 4 — Примите элемент меню «Пуск» по умолчанию, который будет создан, и нажмите «Далее».

Пункт меню «Пуск»

Шаг 5 — После завершения установки нажмите «Закрыть», чтобы завершить установку.

Установка завершена

Erlang Configuration

После завершения установки необходимо выполнить следующую настройку, чтобы Erlang начал работать в системе.

Операционные системы Выход
Windows Добавить строку; C: \ Program Files (x86) \ erl7.2.1 \ bin ИЛИ C: \ Program Files \ erl7.2.1 \ bin до конца системной переменной PATH.

Если вы сейчас откроете командную строку и наберете erl , вы сможете получить командную строку erl.

Erlang Configuration

Поздравляем, теперь вы успешно настроили erl на своем ноутбуке.

Установка плагинов в популярных IDE

Erlang как язык программирования также доступен в популярных IDE, таких как Eclipse и IntelliJ . Давайте посмотрим, как мы можем получить необходимые плагины в этих IDE, чтобы у вас было больше возможностей для работы с Erlang.

Установка в Eclipse

Шаг 1 — Откройте Eclipse и выберите пункт меню, Справка → Установить новое программное обеспечение .

Установка в Eclipse

Шаг 2 — Введите Работу со ссылкой как https://download.erlide.org/update

Затем нажмите Добавить.

Войти в работу

Шаг 3 — Вам будет предложено ввести имя для плагина, введите имя как Erlide . Нажмите ОК.

Введите имя плагина

Шаг 4 — Eclipse просканирует предоставленную ссылку и получит необходимые плагины. Проверьте плагины и нажмите Далее.

Получить необходимый плагин

Шаг 5 — В следующем диалоговом окне Eclipse покажет все компоненты, которые будут установлены. Нажмите кнопку «Далее.

Установленные компоненты

Шаг 6 — В следующем диалоговом окне Eclipse просто попросит просмотреть устанавливаемые компоненты. Нажмите кнопку «Далее.

Обзор установленных компонентов

Шаг 7 — В следующем диалоговом окне вам просто нужно принять лицензионное соглашение. Наконец, нажмите кнопку Готово.

Принять лицензионное соглашение

Затем начнется установка, и после ее завершения вам будет предложено перезапустить Eclipse.

После перезапуска Eclipse при создании проекта вы также сможете увидеть Erlang в качестве опции.

Erlang Option

Установка в IntelliJ

Пожалуйста, выполните следующие шаги, чтобы установить IntelliJ на ваш компьютер.

Шаг 1 — Откройте IntelliJ и нажмите Конфигурировать → Плагины.

IntelliJ

Шаг 2 — Введите Erlang в поле поиска. Вы получите плагин Erlang в правой части экрана. Нажмите кнопку Установить.

Erlang Plugin

Шаг 3 — После установки плагина Erlang вам будет предложено перезапустить IDE.

Перезапустите IDE

Когда вы перезапустите IDE и попытаетесь создать новый проект, вы увидите возможность создать проект Erlang.

Erlang Project Option

Erlang — основной синтаксис

Чтобы понять основной синтаксис Erlang, давайте сначала рассмотрим простую программу Hello World .

пример

Live Demo

% hello world program
-module(helloworld). 
-export([start/0]). 

start() -> 
   io:fwrite("Hello, world!\n").

Следующие вещи должны быть отмечены о вышеупомянутой программе —

  • Знак% используется для добавления комментариев к программе.

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

  • Функция экспорта используется для того, чтобы можно было использовать любую функцию, определенную в программе. Мы определяем функцию с именем start, и чтобы использовать функцию start, мы должны использовать оператор экспорта. / 0 означает, что наша функция ‘start’ принимает 0 параметров.

  • Мы наконец определим нашу начальную функцию. Здесь мы используем другой модуль с именем io, который имеет все необходимые функции ввода-вывода в Erlang. Мы использовали функцию fwrite для вывода «Hello World» на консоль.

Знак% используется для добавления комментариев к программе.

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

Функция экспорта используется для того, чтобы можно было использовать любую функцию, определенную в программе. Мы определяем функцию с именем start, и чтобы использовать функцию start, мы должны использовать оператор экспорта. / 0 означает, что наша функция ‘start’ принимает 0 параметров.

Мы наконец определим нашу начальную функцию. Здесь мы используем другой модуль с именем io, который имеет все необходимые функции ввода-вывода в Erlang. Мы использовали функцию fwrite для вывода «Hello World» на консоль.

Выход вышеупомянутой программы будет —

Выход

Hello, world!

Общая форма заявления

В Erlang вы видели, что в языке Erlang используются разные символы. Давайте пройдемся по тому, что мы видели в простой программе Hello World —

  • Символ дефиса (-) обычно используется вместе с модулем, оператором импорта и экспорта. Символ дефиса используется для придания значения каждому утверждению соответственно. Так что примеры из программы Hello world показаны в следующей программе —

Символ дефиса (-) обычно используется вместе с модулем, оператором импорта и экспорта. Символ дефиса используется для придания значения каждому утверждению соответственно. Так что примеры из программы Hello world показаны в следующей программе —

-module(helloworld).
-export([start/0]).

Каждое утверждение ограничено символом точки (.) . Каждое утверждение в Erlang должно заканчиваться этим разделителем. Пример из программы Hello world, как показано в следующей программе —

io:fwrite("Hello, world!\n").
  • Символ косой черты (/) используется вместе с функцией для определения количества параметров, которые принимаются функцией.

Символ косой черты (/) используется вместе с функцией для определения количества параметров, которые принимаются функцией.

-export([start/0]).

Модули

В Erlang весь код разделен на модули. Модуль состоит из последовательности атрибутов и объявлений функций. Это похоже на концепцию пространства имен в других языках программирования, которая используется для логического разделения различных блоков кода.

Определение модуля

Модуль определяется с помощью идентификатора модуля. Общий синтаксис и пример следующие.

Синтаксис

-module(ModuleName)

Имя модуля должно совпадать с именем файла минус расширение .erl . В противном случае загрузка кода не будет работать так, как задумано.

пример

-module(helloworld)

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

Импорт заявления в Эрланге

В Erlang, если кто-то хочет использовать функциональность существующего модуля Erlang, можно использовать оператор импорта. Общая форма заявления на импорт изображена в следующей программе —

пример

-import (modulename, [functionname/parameter]).

Куда,

  • Modulename — это имя модуля, который необходимо импортировать.

  • имя_функции / параметр — функция в модуле, которую необходимо импортировать.

Modulename — это имя модуля, который необходимо импортировать.

имя_функции / параметр — функция в модуле, которую необходимо импортировать.

Давайте изменим способ написания нашей программы hello world для использования оператора import. Пример будет таким, как показано в следующей программе.

пример

% hello world program
-module(helloworld).
-import(io,[fwrite/1]).
-export([start/0]).

start() ->
   fwrite("Hello, world!\n").

В приведенном выше коде мы используем ключевое слово import для импорта библиотеки ‘io’ и, в частности, функцию fwrite . Поэтому теперь, когда мы вызываем функцию fwrite, нам не нужно нигде упоминать имя модуля io .

Ключевые слова в Erlang

Ключевое слово — это зарезервированное слово в Erlang, которое не должно использоваться для каких-либо иных целей, кроме цели, для которой оно предназначено. Ниже приведен список ключевых слов в Erlang.

после а также а также группа
начать BNOT бора BSL
BSR BXOR дело ловить
конд ДИВ конец веселье
если позволять не из
или же OrElse Получать рем
пытаться когда исключающее

Комментарии в Erlang

Комментарии используются для документирования вашего кода. Однострочные комментарии идентифицируются с помощью символа % в любой позиции в строке. Ниже приведен пример для того же —

пример

% hello world program
-module(helloworld).
% import function used to import the io module
-import(io,[fwrite/1]).
% export function used to ensure the start function can be accessed.
-export([start/0]).

start() ->
   fwrite("Hello, world!\n").

Эрланг — Шелл

Оболочка Erlang используется для тестирования выражений. Следовательно, тестирование может быть выполнено в оболочке очень легко, прежде чем оно будет фактически протестировано в самом приложении.

В следующем примере показано, как выражение сложения можно использовать в оболочке. Здесь необходимо отметить, что выражение должно заканчиваться точкой (.).

Ракушка

После выполнения команды оболочка выводит еще одно приглашение, на этот раз для команды № 2 (поскольку номер команды увеличивается при каждом вводе новой команды).

Следующие функции являются наиболее распространенными в оболочке Erlang.

  • b () — печатает текущие привязки переменных.

  • Синтаксис — b ().

  • Например — Ниже приведен пример использования функции. Сначала определяется переменная с именем Str , которая имеет значение abcd . Затем b () используется для отображения всех связанных переменных.

b () — печатает текущие привязки переменных.

Синтаксис — b ().

Например — Ниже приведен пример использования функции. Сначала определяется переменная с именем Str , которая имеет значение abcd . Затем b () используется для отображения всех связанных переменных.

Erlang Shell b ()

  • f () — Удаляет все текущие привязки переменных.

  • Синтаксис — f ().

  • Например — Ниже приведен пример использования функции. Сначала определяется переменная с именем Str, которая имеет значение abcd. Затем f () используется для удаления привязки переменной Str. Затем вызывается b (), чтобы убедиться, что привязка была успешно удалена.

f () — Удаляет все текущие привязки переменных.

Синтаксис — f ().

Например — Ниже приведен пример использования функции. Сначала определяется переменная с именем Str, которая имеет значение abcd. Затем f () используется для удаления привязки переменной Str. Затем вызывается b (), чтобы убедиться, что привязка была успешно удалена.

Erlang Shell f ()

  • f (x) — удаляет привязку для определенной переменной.

  • Синтаксис — f (x). Где x — переменная, для которой необходимо удалить привязку.

  • Например — Ниже приведен пример использования функции. Сначала определяются переменные с именами Str и Str1. Затем f (Str) используется для удаления привязки переменной Str. Затем вызывается b (), чтобы убедиться, что привязка была успешно удалена.

f (x) — удаляет привязку для определенной переменной.

Синтаксис — f (x). Где x — переменная, для которой необходимо удалить привязку.

Например — Ниже приведен пример использования функции. Сначала определяются переменные с именами Str и Str1. Затем f (Str) используется для удаления привязки переменной Str. Затем вызывается b (), чтобы убедиться, что привязка была успешно удалена.

Erlang Shell f (x)

  • h () — печатает список истории всех команд, выполненных в оболочке.

  • Синтаксис — h ().

  • Например — Пример команды h (), которая печатает историю команд, выполненных в оболочке, показан на следующем снимке экрана.

h () — печатает список истории всех команд, выполненных в оболочке.

Синтаксис — h ().

Например — Пример команды h (), которая печатает историю команд, выполненных в оболочке, показан на следующем снимке экрана.

Erlang Shell h ()

  • history (N) — Устанавливает количество предыдущих команд для сохранения в списке истории равным N. Предыдущее число возвращается. Номер по умолчанию — 20.

  • Синтаксис — история (N). Где N — номер, которым должен быть ограничен список истории команд.

  • Например — Пример команды history (N) показан на следующем снимке экрана.

history (N) — Устанавливает количество предыдущих команд для сохранения в списке истории равным N. Предыдущее число возвращается. Номер по умолчанию — 20.

Синтаксис — история (N). Где N — номер, которым должен быть ограничен список истории команд.

Например — Пример команды history (N) показан на следующем снимке экрана.

Erlang Shell история (N)

  • e (N) — повторяет команду N, если N положительно. Если оно отрицательное, N- я предыдущая команда повторяется (т. Е. E (-1) повторяет предыдущую команду).

  • Синтаксис — e (N). Где N — команда на N- й позиции в списке.

  • Например — Пример команды e (N) показан ниже. Поскольку мы выполнили команду e (-1), она выполнит предыдущую команду, которая была history (5).

e (N) — повторяет команду N, если N положительно. Если оно отрицательное, N- я предыдущая команда повторяется (т. Е. E (-1) повторяет предыдущую команду).

Синтаксис — e (N). Где N — команда на N- й позиции в списке.

Например — Пример команды e (N) показан ниже. Поскольку мы выполнили команду e (-1), она выполнит предыдущую команду, которая была history (5).

Erlang Shell e (N)

Эрланг — Типы данных

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

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

Встроенные типы данных

Erlang предлагает широкий спектр встроенных типов данных. Ниже приведен список типов данных, которые определены в Erlang —

  • Число — в Erlang есть 2 типа числовых литералов, которые являются целыми числами и числами с плавающей точкой.

  • Атом — Атом — это литерал, константа с именем. Атом должен быть заключен в одинарные кавычки (‘), если он не начинается со строчной буквы или содержит другие символы, кроме буквенно-цифровых символов, подчеркивания (_) или @.

  • Boolean — Булевы типы данных в Erlang — это два зарезервированных атома: true и false.

  • Битовая строка — битовая строка используется для хранения области нетипизированной памяти.

  • Кортеж — кортеж — это составной тип данных с фиксированным числом терминов. Каждый термин в кортеже называется элементом. Количество элементов называется размером кортежа.

  • Карта — карта — это составной тип данных с переменным числом ассоциаций ключ-значение. Каждая ассоциация ключ-значение на карте называется парой ассоциации. Ключевые и значимые части пары называются элементами. Количество пар ассоциаций называется размером карты.

  • Список — список — это составной тип данных с переменным количеством терминов. Каждый термин в списке называется элементом. Количество элементов называется длиной списка.

Число — в Erlang есть 2 типа числовых литералов, которые являются целыми числами и числами с плавающей точкой.

Атом — Атом — это литерал, константа с именем. Атом должен быть заключен в одинарные кавычки (‘), если он не начинается со строчной буквы или содержит другие символы, кроме буквенно-цифровых символов, подчеркивания (_) или @.

Boolean — Булевы типы данных в Erlang — это два зарезервированных атома: true и false.

Битовая строка — битовая строка используется для хранения области нетипизированной памяти.

Кортеж — кортеж — это составной тип данных с фиксированным числом терминов. Каждый термин в кортеже называется элементом. Количество элементов называется размером кортежа.

Карта — карта — это составной тип данных с переменным числом ассоциаций ключ-значение. Каждая ассоциация ключ-значение на карте называется парой ассоциации. Ключевые и значимые части пары называются элементами. Количество пар ассоциаций называется размером карты.

Список — список — это составной тип данных с переменным количеством терминов. Каждый термин в списке называется элементом. Количество элементов называется длиной списка.

Примечание. Вы будете удивлены тем, что нигде в списке выше не видите тип String. Это потому, что нет строкового типа данных, определенного исключительно в Erlang. Но мы увидим, как мы можем работать со строками в следующей главе.

Ниже приведены примеры использования каждого типа данных. Опять же, каждый тип данных будет подробно обсуждаться в следующих главах. Это просто для ознакомления с кратким описанием вышеупомянутых типов данных.

Число

Пример использования числового типа данных показан в следующей программе. Эта программа показывает сложение 2 целых чисел.

пример

Live Demo

-module(helloworld).
-export([start/0]).

start() ->
   io:fwrite("~w",[1+1]).

Выход вышеупомянутой программы будет —

Выход

2

Атом

Атомы должны начинаться со строчной буквы и могут содержать строчные и прописные буквы, цифры, подчеркивание (_) и знак «at» (@) . Мы также можем заключить атом в одинарные кавычки.

Пример того, как можно использовать тип данных Atom, показан в следующей программе. В этой программе мы создаем атом, который называется atom1.

пример

Live Demo

-module(helloworld).
-export([start/0]).

start() ->
   io:fwrite(atom1).

Выход вышеупомянутой программы будет —

Выход

atom1

логический

Пример использования логического типа данных показан в следующей программе. В этом примере выполняется сравнение между двумя целыми числами и выводится полученное логическое значение на консоль.

пример

Live Demo

-module(helloworld).
-export([start/0]).

start() ->
   io:fwrite(2 =< 3).

Выход вышеупомянутой программы будет —

Выход

true

Битовая строка

Пример использования типа данных Bit String показан в следующей программе. Эта программа определяет битовую строку, состоящую из 2 битов. Binary_to_list — это встроенная функция, определенная в Erlang, которую можно использовать для преобразования битовой строки в список.

пример

Live Demo

-module(helloworld).
-export([start/0]).

start() ->
   Bin1 = <<10,20>>,
   X = binary_to_list(Bin1),
   io:fwrite("~w",[X]).

Выход вышеупомянутой программы будет —

Выход

[10,20]

Кортеж

Пример использования типа данных Tuple показан в следующей программе.

Здесь мы определяем кортеж P, который имеет 3 члена. Tuple_size — это встроенная функция, определенная в Erlang, которая может использоваться для определения размера кортежа.

пример

Live Demo

-module(helloworld). 
-export([start/0]). 

start() -> 
   P = {john,24,{june,25}} , 
   io:fwrite("~w",[tuple_size(P)]).

Выход вышеупомянутой программы будет —

Выход

3

карта

Пример того, как можно использовать тип данных Map, показан в следующей программе.

Здесь мы определяем карту M1, которая имеет 2 отображения. Map_size — это встроенная функция, определенная в Erlang, которая может использоваться для определения размера карты.

пример

Live Demo

-module(helloworld). 
-export([start/0]). 

start() -> 
   M1 = #{name=>john,age=>25}, 
   io:fwrite("~w",[map_size(M1)]).

Выход вышеупомянутой программы будет —

Выход

2

Список

Пример того, как можно использовать тип данных List, показан в следующей программе.

Здесь мы определяем список L, который имеет 3 элемента. Длина — это встроенная функция, определенная в Erlang, которая может использоваться для определения размера списка.

пример

Live Demo

-module(helloworld). 
-export([start/0]). 

start() -> 
   L = [10,20,30] , 
   io:fwrite("~w",[length(L)]).

Выход вышеупомянутой программы будет —

Выход

3

Erlang — переменные

В Erlang все переменные связаны с оператором ‘=’. Все переменные должны начинаться с символа верхнего регистра. В других языках программирования знак «=» используется для назначения, но не в случае с Erlang. Как уже говорилось, переменные определяются с помощью оператора ‘=’.

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

Следующие основные переменные в Erlang объясняются в последней главе —

  • Числа — это используется, чтобы представить целое число или число с плавающей точкой. Пример 10.

  • Boolean — Представляет логическое значение, которое может быть истинным или ложным.

  • Битовая строка — битовая строка используется для хранения области нетипизированной памяти. Пример << 40,50 >>.

  • Кортеж — кортеж — это составной тип данных с фиксированным числом терминов. Примером является {40,50}.

  • Карта — карта — это составной тип данных с переменным числом ассоциаций ключ-значение. Каждая ассоциация ключ-значение на карте называется парой ассоциации. Примером является {type => person, age => 25}.

  • Список — список — это составной тип данных с переменным количеством терминов. Примером является [40,40].

Числа — это используется, чтобы представить целое число или число с плавающей точкой. Пример 10.

Boolean — Представляет логическое значение, которое может быть истинным или ложным.

Битовая строка — битовая строка используется для хранения области нетипизированной памяти. Пример << 40,50 >>.

Кортеж — кортеж — это составной тип данных с фиксированным числом терминов. Примером является {40,50}.

Карта — карта — это составной тип данных с переменным числом ассоциаций ключ-значение. Каждая ассоциация ключ-значение на карте называется парой ассоциации. Примером является {type => person, age => 25}.

Список — список — это составной тип данных с переменным количеством терминов. Примером является [40,40].

Объявления переменных

Общий синтаксис определения переменной следующий:

Синтаксис

var-name = var-value

Куда,

  • var-name — это имя переменной.

  • var-value — это значение, связанное с переменной.

var-name — это имя переменной.

var-value — это значение, связанное с переменной.

Ниже приведен пример объявления переменной:

пример

Live Demo

-module(helloworld). 
-export([start/0]). 

start() -> 
   X = 40, 
   Y = 50, 
   Result = X + Y, 
   io:fwrite("~w",[Result]).

В приведенном выше примере у нас есть 2 переменные, одна из которых X, которая связана со значением 40, а следующая Y, которая связана со значением 50. Другая переменная с именем Result связана с добавлением X и Y.

Выход вышеупомянутой программы будет —

Выход

90

Именование переменных

Как уже говорилось, имена переменных должны начинаться с заглавных букв. Давайте рассмотрим пример переменной, объявленной в нижнем регистре.

пример

Live Demo

-module(helloworld). 
-export([start/0]). 

start() -> 
   X = 40, 
   Y = 50, 
   result = X + Y, 
   io:fwrite("~w",[Result]).

Если вы попытаетесь скомпилировать вышеуказанную программу, вы получите следующую ошибку времени компиляции.

Выход

helloworld.erl:8: variable 'Result' is unbound

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

пример

Live Demo

-module(helloworld). 
-export([start/0]). 

start() -> 
   X = 40, 
   Y = 50, 
   X = 60, 
   io:fwrite("~w",[X]).

Если вы попытаетесь скомпилировать вышеуказанную программу, вы получите следующую ошибку времени компиляции.

Выход

helloworld.erl:6: Warning: variable 'Y' is unused
helloworld.erl:7: Warning: no clause will ever match
helloworld.erl:7: Warning: the guard for this clause evaluates to 'false'

Переменные печати

В этом разделе мы обсудим, как использовать различные функции печати переменных.

Использование функции io: fwrite

Вы бы видели, как это (io: fwrite) используется во всех вышеперечисленных программах. Функция fwrite является частью модуля ‘io’ или Erlang, который может использоваться для вывода значения переменных в программе.

В следующем примере показано еще несколько параметров, которые можно использовать с оператором fwrite.

пример

Live Demo

-module(helloworld). 
-export([start/0]). 

start() -> 
   X = 40.00, 
   Y = 50.00, 
   io:fwrite("~f~n",[X]), 
   io:fwrite("~e",[Y]).

Выход вышеупомянутой программы будет —

Выход

40.000000
5.00000e+1

Следующие указатели должны быть отмечены о вышеупомянутой программе.

  • ~ — Этот символ символизирует необходимость некоторого форматирования для вывода.

  • ~ f — Аргумент — это число с плавающей точкой, которое записывается как [-] ddd.ddd, где точность — это число цифр после десятичной точки. Точность по умолчанию равна 6, и она не может быть меньше 1.

  • ~ n — Это для печати на новую строку.

  • ~ e — Аргумент — это число с плавающей точкой, которое записывается как [-] d.ddde + -ddd, где точность — это количество записанных цифр. Точность по умолчанию равна 6, и она не может быть меньше 2.

~ — Этот символ символизирует необходимость некоторого форматирования для вывода.

~ f — Аргумент — это число с плавающей точкой, которое записывается как [-] ddd.ddd, где точность — это число цифр после десятичной точки. Точность по умолчанию равна 6, и она не может быть меньше 1.

~ n — Это для печати на новую строку.

~ e — Аргумент — это число с плавающей точкой, которое записывается как [-] d.ddde + -ddd, где точность — это количество записанных цифр. Точность по умолчанию равна 6, и она не может быть меньше 2.

Эрланг — Операторы

Оператор — это символ, который указывает компилятору выполнять определенные математические или логические манипуляции.

Эрланг имеет следующий тип операторов —

  • Арифметические операторы
  • Реляционные операторы
  • Логические операторы
  • Битовые операторы

Арифметические Операторы

Эрлангский язык поддерживает нормальные арифметические операторы как любой язык. Ниже приведены арифметические операторы, доступные в Erlang.

Показать примеры

оператор Описание пример
+ Добавление двух операндов 1 + 2 даст 3
Вычитает второй операнд из первого 1 — 2 даст -1
* Умножение обоих операндов 2 * 2 даст 4
/ Деление числителя по знаменателю 2/2 даст 1
рем Остаток от деления первого числа на второе 3 бэма 2 даст 1
ДИВ Компонент div выполнит деление и вернет целочисленный компонент. 3 div 2 даст 1

Операторы отношений

Реляционные операторы позволяют сравнивать объекты. Ниже приведены реляционные операторы, доступные в Erlang.

Показать примеры

оператор Описание пример
== Проверяет равенство между двумя объектами 2 = 2 даст истинное
знак равно Проверяет разницу между двумя объектами 3 / = 2 даст истинное
< Проверяет, является ли левый объект меньше правого операнда. 2 <3 даст истинное
= < Проверяет, является ли левый объект меньше или равен правому операнду. 2 = <3 даст истинное
> Проверяет, является ли левый объект больше правого операнда. 3> 2 даст истинное
> = Проверяет, является ли левый объект больше или равен правому операнду. 3> = 2 даст истинное

Логические Операторы

Эти логические операторы используются для оценки логических выражений. Ниже приведены логические операторы, доступные в Erlang.

Показать примеры

оператор Описание пример
или же Это логический оператор «или» правда или правда даст правда
а также Это логический оператор «и» Истина и ложь дадут ложь
не Это логический оператор «не» не ложь даст правду
исключающее Это логический эксклюзивный оператор «xor» Правда хор ложь даст правда

Битовые операторы

Эрланг предоставляет четыре побитовых оператора. Ниже приведены побитовые операторы, доступные в Erlang.

Показать примеры

Sr.No. Оператор и описание
1

группа

Это побитовый оператор «и»

2

бора

Это побитовый оператор «или»

3

BXOR

Это побитовый «xor» или Exclusive или оператор

4

BNOT

Это побитовый оператор отрицания

группа

Это побитовый оператор «и»

бора

Это побитовый оператор «или»

BXOR

Это побитовый «xor» или Exclusive или оператор

BNOT

Это побитовый оператор отрицания

Ниже приведена таблица истинности, демонстрирующая этих операторов:

п Q P & Q р | Q р ^ д
0 0 0 0 0
0 1 0 1 1
1 1 1 1 0
1 0 0 1 1

Приоритет оператора

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

операторы Ассоциативность
:
#
BNOT, не
/, *, Отд, бэр, группа, и Левый ассоциативный
+, -, бора, BXOR, или, исключающие Левый ассоциативный
==, / =, = <, <,> =,>

Эрланг — Петли

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

при реализации заявления

Поскольку в Erlang нет прямого оператора while, необходимо использовать методы рекурсии, доступные в Erlang, для реализации оператора while.

Мы попытаемся следовать той же реализации цикла while, что и в других языках программирования. Ниже приводится общий поток, который будет следовать.

при реализации заявления

Давайте рассмотрим пример того, как мы можем использовать рекурсию для реализации цикла while в Erlang.

пример

Live Demo

-module(helloworld). 
-export([while/1,while/2, start/0]). 

while(L) -> while(L,0). 
while([], Acc) -> Acc;

while([_|T], Acc) ->
   io:fwrite("~w~n",[Acc]), 
   while(T,Acc+1). 
   
   start() -> 
   X = [1,2,3,4], 
   while(X).

Следующие ключевые моменты должны быть отмечены о вышеупомянутой программе —

  • Определите рекурсивную функцию, вызываемую while, которая будет имитировать реализацию нашего цикла while.

  • Введите в качестве примера список значений, определенных в переменной X, для нашей функции while.

  • Функция while принимает каждое значение списка и сохраняет промежуточное значение в переменной «Acc».

  • Затем цикл while вызывается рекурсивно для каждого значения в списке.

Определите рекурсивную функцию, вызываемую while, которая будет имитировать реализацию нашего цикла while.

Введите в качестве примера список значений, определенных в переменной X, для нашей функции while.

Функция while принимает каждое значение списка и сохраняет промежуточное значение в переменной «Acc».

Затем цикл while вызывается рекурсивно для каждого значения в списке.

Вывод приведенного выше кода будет —

Выход

0
1
2
3

для заявления

Поскольку в Erlang нет прямого выражения для оператора, необходимо использовать методы рекурсии, доступные в Erlang, для реализации оператора for .

Мы попытаемся следовать той же реализации цикла for, что и в других языках программирования. Ниже приводится общий порядок действий, которого следует придерживаться.

для заявления

Давайте рассмотрим пример того, как мы можем использовать рекурсию для реализации цикла for в Erlang.

пример

Live Demo

-module(helloworld). 
-export([for/2,start/0]). 

for(0,_) -> 
   []; 
   
   for(N,Term) when N > 0 -> 
   io:fwrite("Hello~n"), 
   [Term|for(N-1,Term)]. 
   
start() -> 
   for(5,1).

Следующие ключевые моменты должны быть отмечены о вышеупомянутой программе —

  • Мы определяем рекурсивную функцию, которая будет имитировать реализацию нашего цикла for .

  • Мы используем защитный элемент в функции «for», чтобы гарантировать, что значение N или ограничение является положительным значением.

  • Мы рекурсивно вызываем функцию for, уменьшая значение N при каждой рекурсии.

Мы определяем рекурсивную функцию, которая будет имитировать реализацию нашего цикла for .

Мы используем защитный элемент в функции «for», чтобы гарантировать, что значение N или ограничение является положительным значением.

Мы рекурсивно вызываем функцию for, уменьшая значение N при каждой рекурсии.

Вывод приведенного выше кода будет —

Выход

Hello
Hello
Hello
Hello
Hello

Эрланг — Принятие решений

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

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

Принятие решения

Язык программирования Erlang предоставляет следующие типы операторов принятия решений.

Sr.No. Заявление и описание
1

Если заявление

Оператор if состоит из логического выражения, за которым следует один или несколько операторов.

2

Множественное выражение

Выражение if также позволяет вычислять несколько выражений одновременно.

3

Вложенные, если заявления

Вы можете использовать один оператор if или else if внутри другого оператора if или else if .

4

Заявления по делу

Его можно использовать для выполнения выражений на основе выходных данных оператора case.

Если заявление

Оператор if состоит из логического выражения, за которым следует один или несколько операторов.

Множественное выражение

Выражение if также позволяет вычислять несколько выражений одновременно.

Вложенные, если заявления

Вы можете использовать один оператор if или else if внутри другого оператора if или else if .

Заявления по делу

Его можно использовать для выполнения выражений на основе выходных данных оператора case.

Эрланг — Функции

Erlang известен как функциональный язык программирования, поэтому вы ожидаете увидеть много внимания тому, как функции работают в Erlang. В этой главе рассказывается, что можно сделать с помощью функций в Erlang.

Определение функции

Синтаксис объявления функции следующий:

Синтаксис

FunctionName(Pattern1… PatternN) ->
Body;

Куда,

  • FunctionName — имя функции является атомом.

  • Pattern1… PatternN — каждый аргумент является шаблоном. Число аргументов N является арностью функции. Функция однозначно определяется именем модуля, именем функции и арностью. То есть две функции с одинаковым именем и в одном и том же модуле, но с разными арностями — это две разные функции.

  • Тело. Тело предложения состоит из последовательности выражений, разделенных запятой (,):

FunctionName — имя функции является атомом.

Pattern1… PatternN — каждый аргумент является шаблоном. Число аргументов N является арностью функции. Функция однозначно определяется именем модуля, именем функции и арностью. То есть две функции с одинаковым именем и в одном и том же модуле, но с разными арностями — это две разные функции.

Тело. Тело предложения состоит из последовательности выражений, разделенных запятой (,):

Следующая программа представляет собой простой пример использования функций —

пример

Live Demo

-module(helloworld). 
-export([add/2,start/0]). 

add(X,Y) -> 
   Z = X+Y, 
   io:fwrite("~w~n",[Z]). 
   
start() -> 
   add(5,6).

Следующие указатели должны быть отмечены о вышеупомянутой программе —

  • Мы определяем две функции, одна называется add, которая принимает 2 параметра, а другая является функцией start .

  • Обе функции определены с помощью функции экспорта. Если мы этого не сделаем, мы не сможем использовать эту функцию.

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

Мы определяем две функции, одна называется add, которая принимает 2 параметра, а другая является функцией start .

Обе функции определены с помощью функции экспорта. Если мы этого не сделаем, мы не сможем использовать эту функцию.

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

Выход вышеупомянутой программы будет —

Выход

11

Анонимные функции

Анонимная функция — это функция, с которой не связано имя. Erlang имеет возможность определять анонимные функции. Следующая программа является примером анонимной функции.

пример

Live Demo

-module(helloworld). 
-export([start/0]). 

start() -> 
   Fn = fun() -> 
      io:fwrite("Anonymous Function") end, 
   Fn().

Следующие пункты должны быть отмечены о приведенном выше примере —

  • Анонимная функция определяется с помощью ключевого слова fun () .

  • Функция назначена переменной с именем Fn.

  • Функция вызывается через имя переменной.

Анонимная функция определяется с помощью ключевого слова fun () .

Функция назначена переменной с именем Fn.

Функция вызывается через имя переменной.

Выход вышеупомянутой программы будет —

Выход

Anonymous Function

Функции с несколькими аргументами

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

В следующем примере демонстрация функции определяется с несколькими аргументами для каждого определения функции.

пример

Live Demo

-module(helloworld). 
-export([add/2,add/3,start/0]). 

add(X,Y) -> 
   Z = X+Y, 
   io:fwrite("~w~n",[Z]). 
   
add(X,Y,Z) -> 
   A = X+Y+Z, 
   io:fwrite("~w~n",[A]). 
 
start() ->
   add(5,6), 
   add(5,6,6).

В приведенной выше программе мы определяем функцию добавления дважды. Но определение первой функции добавления принимает два параметра, а второй — три параметра.

Выход вышеупомянутой программы будет —

Выход

11
17

Функции с защитными последовательностями

Функции в Erlang также могут иметь защитные последовательности. Это не что иное, как выражения, которые только при значении true будут запускать функцию.

Синтаксис функции с защитной последовательностью показан в следующей программе.

Синтаксис

FunctionName(Pattern1… PatternN) [when GuardSeq1]->
Body;

Куда,

  • FunctionName — имя функции является атомом.

  • Pattern1… PatternN — каждый аргумент является шаблоном. Число аргументов N является арностью функции. Функция однозначно определяется именем модуля, именем функции и арностью. То есть две функции с одинаковым именем и в одном и том же модуле, но с разными арностями — это две разные функции.

  • Тело. Тело предложения состоит из последовательности выражений, разделенных запятой (,).

  • GuardSeq1 — это выражение, которое вычисляется при вызове функции.

FunctionName — имя функции является атомом.

Pattern1… PatternN — каждый аргумент является шаблоном. Число аргументов N является арностью функции. Функция однозначно определяется именем модуля, именем функции и арностью. То есть две функции с одинаковым именем и в одном и том же модуле, но с разными арностями — это две разные функции.

Тело. Тело предложения состоит из последовательности выражений, разделенных запятой (,).

GuardSeq1 — это выражение, которое вычисляется при вызове функции.

Следующая программа представляет собой простой пример использования функции с защитной последовательностью.

пример

Live Demo

-module(helloworld). 
-export([add/1,start/0]). 

add(X) when X>3 -> 
   io:fwrite("~w~n",[X]). 

start() -> 
   add(4).

Выход вышеуказанной программы —

Выход

4

Если функция add была вызвана как add (3) , программа выдаст ошибку.

Эрланг — Модули

Модули — это набор функций, сгруппированных в одном файле под одним именем. Кроме того, все функции в Erlang должны быть определены в модулях.

Большинство основных функций, таких как арифметические, логические и логические операторы, уже доступны, поскольку модули по умолчанию загружаются при запуске программы. Любая другая функция, определенная в модуле, который вы когда-либо будете использовать, должна вызываться в форме Module: Function (Arguments).

Определение модуля

С помощью модуля вы можете объявить два вида вещей: функции и атрибуты. Атрибуты — это метаданные, описывающие сам модуль, такие как его имя, функции, которые должны быть видны внешнему миру, автор кода и так далее. Этот тип метаданных полезен, потому что он дает советы компилятору о том, как он должен выполнять свою работу, а также потому, что он позволяет людям получать полезную информацию из скомпилированного кода без необходимости обращаться к источнику.

Синтаксис объявления функции следующий:

Синтаксис

-module(modulename)

Где modulename — это имя модуля. Это должна быть первая строка кода в модуле.

Следующая программа показывает пример модуля с именем helloworld .

пример

Live Demo

-module(helloworld). 
-export([start/0]). 

start() -> 
   io:fwrite("Hello World").

Выход вышеуказанной программы —

Выход

Hello World

Атрибуты модуля

Атрибут модуля определяет определенное свойство модуля. Атрибут модуля состоит из тега и значения.

Общий синтаксис атрибута —

Синтаксис

-Tag(Value)

Пример использования атрибута показан в следующей программе:

пример

Live Demo

-module(helloworld). 
-author("TutorialPoint"). 
-version("1.0"). 
-export([start/0]). 

start() -> 
   io:fwrite("Hello World").

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

Выход вышеуказанной программы —

Выход

Hello World

Предварительно построенные атрибуты

Erlang имеет несколько встроенных атрибутов, которые можно прикрепить к модулям. Давайте посмотрим на них.

экспорт

Атрибут export будет принимать список функций и артиклей для экспорта для потребления другими модулями. Это определит интерфейс модуля. Мы уже видели это во всех наших предыдущих примерах.

Синтаксис

export([FunctionName1/FunctionArity1,.,FunctionNameN/FunctionArityN])

Куда,

  • FunctionName — это имя функции в программе.

  • FunctionArity — количество параметров, связанных с функцией.

FunctionName — это имя функции в программе.

FunctionArity — количество параметров, связанных с функцией.

пример

Live Demo

-module(helloworld). 
-author("TutorialPoint"). 
-version("1.0"). 
-export([start/0]). 

start() -> 
   io:fwrite("Hello World").

Выход вышеупомянутой программы будет —

Выход

Hello World

Импортировать

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

Синтаксис

-import (modulename , [functionname/parameter]).

Куда,

  • Modulename — это имя модуля, который необходимо импортировать.

  • имя функции / параметр — функция в модуле, которую необходимо импортировать.

Modulename — это имя модуля, который необходимо импортировать.

имя функции / параметр — функция в модуле, которую необходимо импортировать.

пример

Live Demo

-module(helloworld). 
-import(io,[fwrite/1]). 
-export([start/0]). 

start() -> 
   fwrite("Hello, world!\n").

В приведенном выше коде мы используем ключевое слово import для импорта библиотеки ‘io’ и, в частности, функцию fwrite. Поэтому теперь, когда мы вызываем функцию fwrite, нам не нужно нигде упоминать имя модуля io.

Выход вышеупомянутой программы будет —

Выход

Hello, world! 

Эрланг — Рекурсия

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

пример

Live Demo

-module(helloworld). 
-export([fac/1,start/0]). 

fac(N) when N == 0 -> 1; 
fac(N) when N > 0 -> N*fac(N-1). 

start() -> 
   X = fac(4), 
   io:fwrite("~w",[X]).

Следующие вещи должны быть отмечены о вышеупомянутой программе —

  • Сначала мы определим функцию с именем fac (N).

  • Мы можем определить рекурсивную функцию, вызывая fac (N) рекурсивно.

Сначала мы определим функцию с именем fac (N).

Мы можем определить рекурсивную функцию, вызывая fac (N) рекурсивно.

Выход вышеуказанной программы —

Выход

24

Практический подход к рекурсии

В этом разделе мы подробно разберем различные типы рекурсий и их использование в Erlang.

Длина рекурсии

Более практичный подход к рекурсии можно увидеть на простом примере, который используется для определения длины списка. Список может иметь несколько значений, например [1,2,3,4]. Давайте использовать рекурсию, чтобы увидеть, как мы можем получить длину списка.

пример

Live Demo

-module(helloworld). 
-export([len/1,start/0]). 

len([]) -> 0; 
len([_|T]) -> 1 + len(T). 

start() -> 
   X = [1,2,3,4], 
   Y = len(X), 
   io:fwrite("~w",[Y]).

Следующие вещи должны быть отмечены о вышеупомянутой программе —

  • Первая функция len ([]) используется для условия особого случая, если список пуст.

  • Шаблон [H | T] для сопоставления со списками одного или нескольких элементов, поскольку список длиной один будет определен как [X | []], а список длиной два будет определен как [X | [Y | [ ]]] . Обратите внимание, что вторым элементом является сам список. Это означает, что нам нужно только сосчитать первый, и функция может вызвать себя для второго элемента. Учитывая, что каждое значение в списке считается длиной 1.

Первая функция len ([]) используется для условия особого случая, если список пуст.

Шаблон [H | T] для сопоставления со списками одного или нескольких элементов, поскольку список длиной один будет определен как [X | []], а список длиной два будет определен как [X | [Y | [ ]]] . Обратите внимание, что вторым элементом является сам список. Это означает, что нам нужно только сосчитать первый, и функция может вызвать себя для второго элемента. Учитывая, что каждое значение в списке считается длиной 1.

Выход вышеупомянутой программы будет —

Выход

4

Хвост Рекурсия

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

Синтаксис

len([]) -> 0; 
len([_|T]) -> 1 + len(T).

Для ответа на 1 + len (Отдых) нужно найти ответ len (Отдых). Затем самой функции len (Rest) нужно было найти результат вызова другой функции. Дополнения будут складываться до тех пор, пока не будет найден последний, и только тогда будет вычислен окончательный результат.

Хвостовая рекурсия направлена ​​на устранение этого сложения операций за счет уменьшения их по мере их возникновения.

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

Давайте посмотрим на пример хвостовой рекурсии —

пример

Live Demo

-module(helloworld).
-export([tail_len/1,tail_len/2,start/0]). 

tail_len(L) -> tail_len(L,0). 
tail_len([], Acc) -> Acc; 
tail_len([_|T], Acc) -> tail_len(T,Acc+1). 

start() -> 
   X = [1,2,3,4], 
   Y = tail_len(X), 
   io:fwrite("~w",[Y]).

Выход вышеуказанной программы —

Выход

4

дублировать

Давайте посмотрим на пример рекурсии. На этот раз давайте напишем функцию, которая принимает целое число в качестве первого параметра, а затем любой другой член в качестве второго параметра. Затем он создаст список из столько копий термина, сколько указано целым числом.

Давайте посмотрим, как будет выглядеть пример этого —

Live Demo

-module(helloworld). 
-export([duplicate/2,start/0]). 

duplicate(0,_) -> 
   []; 
duplicate(N,Term) when N > 0 ->
   io:fwrite("~w,~n",[Term]),
   [Term|duplicate(N-1,Term)]. 
start() -> 
   duplicate(5,1).

Выход вышеупомянутой программы будет —

Выход

1,
1,
1,
1,
1,

Перестановка списка

Не существует границ, по которым вы можете использовать рекурсию в Erlang. Давайте теперь быстро посмотрим, как мы можем обратить элементы списка с помощью рекурсии. Следующая программа может быть использована для достижения этой цели.

пример

Live Demo

-module(helloworld). 
-export([tail_reverse/2,start/0]). 

tail_reverse(L) -> tail_reverse(L,[]).

tail_reverse([],Acc) -> Acc; 
tail_reverse([H|T],Acc) -> tail_reverse(T, [H|Acc]).

start() -> 
   X = [1,2,3,4], 
   Y = tail_reverse(X), 
   io:fwrite("~w",[Y]).

Выход вышеупомянутой программы будет —

Выход

[4,3,2,1]

Следующие вещи должны быть отмечены о вышеупомянутой программе —

  • Мы снова используем концепцию временных переменных для хранения каждого элемента списка в переменной с именем Acc.

  • Затем мы вызываем tail_reverse рекурсивно, но на этот раз мы гарантируем, что последний элемент будет помещен в новый список первым.

  • Затем мы рекурсивно вызываем tail_reverse для каждого элемента в списке.

Мы снова используем концепцию временных переменных для хранения каждого элемента списка в переменной с именем Acc.

Затем мы вызываем tail_reverse рекурсивно, но на этот раз мы гарантируем, что последний элемент будет помещен в новый список первым.

Затем мы рекурсивно вызываем tail_reverse для каждого элемента в списке.

Эрланг — Числа

В Erlang есть 2 типа числовых литералов, которые являются целыми числами и числами с плавающей запятой. Ниже приведены некоторые примеры, которые показывают, как целые числа и числа с плавающей запятой могут использоваться в Erlang.

Целое число — пример того, как числовой тип данных может использоваться как целое число, показан в следующей программе. Эта программа показывает сложение 2 целых чисел.

пример

Live Demo

-module(helloworld). 
-export([start/0]). 

start() -> 
   io:fwrite("~w",[1+1]).

Вывод вышеуказанной программы будет следующим:

Выход

2

Float — пример того, как числовой тип данных может использоваться как число с плавающей точкой, показан в следующей программе. Эта программа показывает сложение 2 целых чисел.

пример

Live Demo

-module(helloworld).
-export([start/0]). 

start() -> 
   io:fwrite("~w",[1.1+1.2]).

Вывод вышеуказанной программы будет следующим:

Выход

2.3

Отображение числа с плавающей запятой и экспоненциальных чисел

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

пример

Live Demo

-module(helloworld). 
-export([start/0]). 

start() -> 
   io:fwrite("~f~n",[1.1+1.2]), 
   io:fwrite("~e~n",[1.1+1.2]).

Вывод вышеуказанной программы будет следующим:

Выход

2.300000
2.30000e+0

Следующие ключевые вещи должны быть отмечены о вышеупомянутой программе —

  • Если указана опция ~ f, это означает, что аргумент является плавающей точкой, которая записывается как [-] ddd.ddd , где точность — это количество цифр после десятичной точки. Точность по умолчанию — 6.

  • Если указана опция ~ e, это означает, что аргумент является плавающей точкой, которая записывается как [-] d.ddde + -ddd , где точность — это количество записанных цифр. Точность по умолчанию — 6.

Если указана опция ~ f, это означает, что аргумент является плавающей точкой, которая записывается как [-] ddd.ddd , где точность — это количество цифр после десятичной точки. Точность по умолчанию — 6.

Если указана опция ~ e, это означает, что аргумент является плавающей точкой, которая записывается как [-] d.ddde + -ddd , где точность — это количество записанных цифр. Точность по умолчанию — 6.

Математические функции для чисел

Следующие математические функции доступны в Erlang для чисел. Обратите внимание, что все математические функции для Эрланга присутствуют в математической библиотеке. Таким образом, все приведенные ниже примеры будут использовать оператор import для импорта всех методов из математической библиотеки.

Sr.No. Математические функции и описание
1

грех

Этот метод возвращает синус указанного значения.

2

соз

Этот метод возвращает косинус указанного значения.

3

загар

Этот метод возвращает тангенс указанного значения.

4

как в

Метод возвращает арксинус указанного значения.

5

экоса

Метод возвращает арккозин указанного значения.

6

загар

Метод возвращает арктангенс указанного значения.

7 ехр

Метод возвращает экспоненту указанного значения.

8

журнал

Метод возвращает логарифмическое значение указанного значения.

9

абс

Метод возвращает абсолютное значение указанного числа.

10

поплавок

Метод преобразует число в значение с плавающей точкой.

11

is_float

Метод проверяет, является ли число значением с плавающей запятой.

12

Is_Integer

Метод проверяет, является ли число целочисленным значением.

грех

Этот метод возвращает синус указанного значения.

соз

Этот метод возвращает косинус указанного значения.

загар

Этот метод возвращает тангенс указанного значения.

как в

Метод возвращает арксинус указанного значения.

экоса

Метод возвращает арккозин указанного значения.

загар

Метод возвращает арктангенс указанного значения.

Метод возвращает экспоненту указанного значения.

журнал

Метод возвращает логарифмическое значение указанного значения.

абс

Метод возвращает абсолютное значение указанного числа.

поплавок

Метод преобразует число в значение с плавающей точкой.

is_float

Метод проверяет, является ли число значением с плавающей запятой.

Is_Integer

Метод проверяет, является ли число целочисленным значением.

Эрланг — Струны

Строковый литерал создается в Erlang, заключая текст строки в кавычки. Строки в Erlang должны быть построены с использованием двойных кавычек, таких как «Hello World».

Ниже приведен пример использования строк в Erlang —

пример

Live Demo

-module(helloworld). 
-export([start/0]). 

start() ->
   Str1 = "This is a string", 
   io:fwrite("~p~n",[Str1]).

В приведенном выше примере создается строковая переменная с именем Str1 . Строка «Это строка» присваивается переменной и отображается соответствующим образом.

Выход вышеупомянутой программы будет —

Выход

“This is a string”

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

Sr.No Строковые методы и описание
1

Len

Метод возвращает длину определенной строки.

2

равный

Метод возвращает логическое значение того, равна ли одна строка другой.

3

CONCAT

Метод объединяет 2 строки и возвращает объединенную строку.

4

CHR

Метод возвращает позицию индекса символа в строке.

5

ул

Метод возвращает позицию индекса подстроки в строке.

6

зиЬзЬг

Метод возвращает подстроку из исходной строки на основе начальной позиции и количества символов из начальной позиции.

7

оставил

Метод возвращает подстроку из исходной строки на основе начальной позиции и количества символов из начальной позиции.

Len

Метод возвращает длину определенной строки.

равный

Метод возвращает логическое значение того, равна ли одна строка другой.

CONCAT

Метод объединяет 2 строки и возвращает объединенную строку.

CHR

Метод возвращает позицию индекса символа в строке.

ул

Метод возвращает позицию индекса подстроки в строке.

зиЬзЬг

Метод возвращает подстроку из исходной строки на основе начальной позиции и количества символов из начальной позиции.

оставил

Метод возвращает подстроку из исходной строки на основе начальной позиции и количества символов из начальной позиции.

осталось с последним символом

Метод возвращает подстроку слева от строки в зависимости от количества символов. Но с возможностью включить завершающий символ, если число больше, чем длина строки.

Синтаксис

left(str1,number,$character)

параметры

  • str1 — это строка, из которой нужно извлечь подстроку.

  • Число — это количество символов, которые должны присутствовать в подстроке.

  • $ Character — символ для включения в качестве завершающего символа.

str1 — это строка, из которой нужно извлечь подстроку.

Число — это количество символов, которые должны присутствовать в подстроке.

$ Character — символ для включения в качестве завершающего символа.

Возвращаемое значение

Возвращает подстроку из исходной строки на основе левой части строки и числа.

Например

Live Demo

-module(helloworld). 
-import(string,[left/3]). 
-export([start/0]). 

start() -> 
   Str1 = "hello", 
   Str2 = left(Str1,10,$.), 
   io:fwrite("~p~n",[Str2]).

Выход

Когда мы запустим вышеуказанную программу, мы получим следующий результат.

"hello....."

право

Метод возвращает подстроку справа от строки в зависимости от количества символов.

Синтаксис

right(str1,number)

параметры

  • str1 — это строка, из которой нужно извлечь подстроку.

  • Число — это количество символов, которые должны присутствовать в подстроке.

str1 — это строка, из которой нужно извлечь подстроку.

Число — это количество символов, которые должны присутствовать в подстроке.

Возвращаемое значение

Возвращает подстроку из исходной строки на основе правой части строки и числа.

Например

Live Demo

-module(helloworld). 
-import(string,[right/2]). 
-export([start/0]). 

start() -> 
   Str1 = "hello World", 
   Str2 = right(Str1,2), 
   io:fwrite("~p~n",[Str2]).

Выход

Когда мы запустим вышеуказанную программу, мы получим следующий результат.

“ld”

прямо с последним символом

Метод возвращает подстроку справа от строки на основе количества символов. Но с возможностью включить завершающий символ, если число больше, чем длина строки.

Синтаксис

right(str1,number,$character)

параметры

  • str1 — это строка, из которой нужно извлечь подстроку.

  • Число — это количество символов, которые должны присутствовать в подстроке.

  • $ Character — символ для включения в качестве завершающего символа.

str1 — это строка, из которой нужно извлечь подстроку.

Число — это количество символов, которые должны присутствовать в подстроке.

$ Character — символ для включения в качестве завершающего символа.

Возвращаемое значение

Возвращает подстроку из исходной строки на основе правой части строки и числа.

Например

Live Demo

-module(helloworld). 
-import(string,[right/3]). 
-export([start/0]). 

start() -> 
   Str1 = "hello", 
   Str2 = right(Str1,10,$.), 
   io:fwrite("~p~n",[Str2]).

Выход

Когда мы запустим вышеуказанную программу, мы получим следующий результат.

".....hello"

снизить

Метод возвращает строку в нижнем регистре.

Синтаксис

to_lower(str1)

параметры

  • str1 — это строка, из которой необходимо преобразовать в нижний регистр.

str1 — это строка, из которой необходимо преобразовать в нижний регистр.

Возвращаемое значение

Возвращает строку в нижнем регистре.

Например

Live Demo

-module(helloworld). 
-import(string,[to_lower/1]). 
-export([start/0]). 

start() -> 
   Str1 = "HELLO WORLD", 
   Str2 = to_lower(Str1), 
   io:fwrite("~p~n",[Str2]).

Выход

Когда мы запустим вышеуказанную программу, мы получим следующий результат.

"hello world"

to_upper

Метод возвращает строку в верхнем регистре.

Синтаксис

to_upper(str1)

параметры

  • str1 — это строка, из которой необходимо преобразовать в верхний регистр.

  • Возвращаемое значение — возвращает строку в верхнем регистре.

str1 — это строка, из которой необходимо преобразовать в верхний регистр.

Возвращаемое значение — возвращает строку в верхнем регистре.

Например

Live Demo

-module(helloworld). 
-import(string,[to_upper/1]). 
-export([start/0]). 

start() -> 
   Str1 = "hello world", 
   Str2 = to_upper(Str1), 
   io:fwrite("~p~n",[Str2]).

Выход

Когда мы запустим вышеуказанную программу, мы получим следующий результат.

"HELLO WORLD"

sub_string

Возвращает подстроку String, начиная с позиции Start до конца строки или до и включая позицию Stop.

Синтаксис

sub_string(str1,start,stop)

параметры

  • str1 — это строка, из которой должна быть возвращена подстрока.

  • start — это начальная позиция подстроки

  • stop — это позиция остановки подстроки

str1 — это строка, из которой должна быть возвращена подстрока.

start — это начальная позиция подстроки

stop — это позиция остановки подстроки

Возвращаемое значение

Возвращает подстроку String, начиная с позиции Start до конца строки или до и включая позицию Stop.

Например

Live Demo

-module(helloworld). 
-import(string,[sub_string/3]). 
-export([start/0]). 

start() -> 
   Str1 = "hello world", 
   Str2 = sub_string(Str1,1,5), 
   io:fwrite("~p~n",[Str2]).

Выход

Когда мы запустим вышеуказанную программу, мы получим следующий результат.

"hello"

Erlang — Списки

Список — это структура, используемая для хранения коллекции элементов данных. В Erlang списки создаются путем заключения значений в квадратные скобки.

Ниже приведен простой пример создания списка чисел в Erlang.

пример

Live Demo

-module(helloworld). 
-export([start/0]). 

start() -> 
   Lst1 = [1,2,3], 
   io:fwrite("~w~n",[Lst1]).

Вывод приведенного выше примера будет —

Выход

[1 2 3]

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

Sr.No Метод и описание
1

все

Возвращает true, если Pred (Elem) возвращает true для всех элементов Elem в List, в противном случае — false.

2

любой

Возвращает true, если Pred (Elem) возвращает true хотя бы для одного элемента Elem в List.

3

присоединять

Возвращает новый список List3, который состоит из элементов List1, за которыми следуют элементы List2.

4

удалять

Удаляет элемент из списка и возвращает новый список.

5

droplast

Удаляет последний элемент списка.

6

дублировать

Возвращает список, который содержит N копий термина Elem

7

прошлой

Возвращает последний элемент списка

8

Максимум

Возвращает элемент списка, который имеет максимальное значение.

9

член

Проверяет, присутствует ли элемент в списке или нет.

10

мин

Возвращает элемент списка, который имеет минимальное значение.

11

сливаться

Возвращает отсортированный список, сформированный путем объединения всех подсписков ListOfLists.

12

энный

Возвращает N-й элемент списка.

13

nthtail

Возвращает N-й хвост списка.

14

задний ход

Переворачивает список элементов.

15

Сортировать

Сортирует список элементов.

16

подсписок

Возвращает подсписок элементов.

17

сумма

Возвращает сумму элементов в списке.

все

Возвращает true, если Pred (Elem) возвращает true для всех элементов Elem в List, в противном случае — false.

любой

Возвращает true, если Pred (Elem) возвращает true хотя бы для одного элемента Elem в List.

присоединять

Возвращает новый список List3, который состоит из элементов List1, за которыми следуют элементы List2.

удалять

Удаляет элемент из списка и возвращает новый список.

droplast

Удаляет последний элемент списка.

дублировать

Возвращает список, который содержит N копий термина Elem

прошлой

Возвращает последний элемент списка

Максимум

Возвращает элемент списка, который имеет максимальное значение.

член

Проверяет, присутствует ли элемент в списке или нет.

мин

Возвращает элемент списка, который имеет минимальное значение.

сливаться

Возвращает отсортированный список, сформированный путем объединения всех подсписков ListOfLists.

энный

Возвращает N-й элемент списка.

nthtail

Возвращает N-й хвост списка.

задний ход

Переворачивает список элементов.

Сортировать

Сортирует список элементов.

подсписок

Возвращает подсписок элементов.

сумма

Возвращает сумму элементов в списке.

Erlang — File I / O

Erlang предоставляет несколько методов при работе с I / O. В нем есть более простые классы для обеспечения следующих функций для файлов:

  • Чтение файлов
  • Запись в файлы
  • Видя, является ли файл файлом или каталогом

Методы работы с файлами в Erlang

Давайте рассмотрим некоторые файловые операции, которые предлагает Erlang. Для целей этих примеров мы будем предполагать, что существует файл с именем NewFile.txt, который содержит следующие строки текста

Example1

Example2

Example3

Этот файл будет использоваться для операций чтения и записи в следующих примерах.

Чтение содержимого файла по одной строке за раз

Общие операции над файлами выполняются с использованием методов, доступных в библиотеке файлов. Для чтения файлов нам нужно сначала использовать операцию открытия, а затем использовать операцию чтения, которая доступна как часть файловой библиотеки. Ниже приводится синтаксис для обоих этих методов.

Синтаксис

  • Открытие файла — Открыть (Файл, Режим)
  • Чтение файла — чтение (FileHandler, NumberofBytes)

параметры

  • Файл — это местоположение файла, который необходимо открыть.

  • Режим — это режим, в котором необходимо открыть файл.

Файл — это местоположение файла, который необходимо открыть.

Режим — это режим, в котором необходимо открыть файл.

Ниже приведены некоторые из доступных режимов —

  • Чтение — файл, который должен существовать, открыт для чтения.

  • Запись — файл открыт для записи. Он создается, если его не существует. Если файл существует, и если запись не совмещена с чтением, файл будет усечен.

  • Добавить — файл будет открыт для записи и будет создан, если он не существует. Каждая операция записи в файл, открытый с помощью append, будет выполняться в конце файла.

  • Эксклюзив — файл, когда он открыт для записи, создается, если он не существует. Если файл существует, open вернет {error, exist}.

Чтение — файл, который должен существовать, открыт для чтения.

Запись — файл открыт для записи. Он создается, если его не существует. Если файл существует, и если запись не совмещена с чтением, файл будет усечен.

Добавить — файл будет открыт для записи и будет создан, если он не существует. Каждая операция записи в файл, открытый с помощью append, будет выполняться в конце файла.

Эксклюзив — файл, когда он открыт для записи, создается, если он не существует. Если файл существует, open вернет {error, exist}.

  • FileHandler — это дескриптор файла. Этот дескриптор будет возвращен при использовании операции file: open .

  • NumberofByte — это количество байтов информации, которую необходимо прочитать из файла.

FileHandler — это дескриптор файла. Этот дескриптор будет возвращен при использовании операции file: open .

NumberofByte — это количество байтов информации, которую необходимо прочитать из файла.

Возвращаемое значение

  • Открыть (Файл, Режим) — возвращает дескриптор файла, если операция прошла успешно.

  • read (FileHandler, NumberofBytes) — возвращает запрашиваемую информацию о прочтении из файла.

Открыть (Файл, Режим) — возвращает дескриптор файла, если операция прошла успешно.

read (FileHandler, NumberofBytes) — возвращает запрашиваемую информацию о прочтении из файла.

Например

-module(helloworld). 
-export([start/0]). 

start() -> 
   {ok, File} = file:open("Newfile.txt",[read]),
   Txt = file:read(File,1024 * 1024), 
   io:fwrite("~p~n",[Txt]).

Вывод — когда мы запустим вышеуказанную программу, мы получим следующий результат.

Example1

Давайте теперь обсудим некоторые другие методы, доступные для файловых операций —

Sr.No. Метод и описание
1

FILE_READ

Доступно для чтения всего содержимого файла за один раз.

2

записывать

Используется для записи содержимого в файл.

3

копия

используется для создания копии существующего файла.

4

удалять

Этот метод используется для удаления существующего файла.

5

list_dir

Этот метод используется для вывода списка содержимого определенного каталога.

6

make_dir

Этот метод используется для создания нового каталога.

7

переименовать

Этот метод используется для переименования существующего файла.

8

размер файла

Этот метод используется для определения размера файла.

9

is_file

Этот метод используется, чтобы определить, является ли файл действительно файлом.

10

is_dir

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

FILE_READ

Доступно для чтения всего содержимого файла за один раз.

записывать

Используется для записи содержимого в файл.

копия

используется для создания копии существующего файла.

удалять

Этот метод используется для удаления существующего файла.

list_dir

Этот метод используется для вывода списка содержимого определенного каталога.

make_dir

Этот метод используется для создания нового каталога.

переименовать

Этот метод используется для переименования существующего файла.

размер файла

Этот метод используется для определения размера файла.

is_file

Этот метод используется, чтобы определить, является ли файл действительно файлом.

is_dir

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

Эрланг — Атомы

Атом — это литерал, константа с именем. Атом должен быть заключен в одинарные кавычки (‘), если он не начинается со строчной буквы или содержит другие символы, кроме буквенно-цифровых символов, подчеркивания (_) или @.

Следующая программа является примером того, как атомы могут быть использованы в Erlang. Эта программа объявляет 3 атома, atom1, atom_1 и ‘atom 1’ соответственно. Таким образом, вы можете увидеть различные способы объявления атома.

пример

Live Demo

-module(helloworld). 
-export([start/0]). 

start() -> 
   io:fwrite(atom1), 
   io:fwrite("~n"), 
   io:fwrite(atom_1), 
   io:fwrite("~n"), 
   io:fwrite('atom 1'), 
   io:fwrite("~n").

Результат вышеупомянутой программы будет следующим:

Выход

atom1

atom_1

atom 1

Давайте посмотрим на некоторые методы, доступные в Erlang для работы с атомами.

Sr.No. Методы и описание
1

is_atom

Этот метод используется для определения, является ли термин действительно атомом.

2

atom_to_list

Этот метод используется для преобразования атома в список.

3

list_to_atom

Этот метод используется для преобразования элемента списка в атом.

4

atom_to_binary

Этот метод используется для преобразования атома в двоичное значение.

5

binary_to_atom

Этот метод используется для преобразования двоичного значения в значение атома.

is_atom

Этот метод используется для определения, является ли термин действительно атомом.

atom_to_list

Этот метод используется для преобразования атома в список.

list_to_atom

Этот метод используется для преобразования элемента списка в атом.

atom_to_binary

Этот метод используется для преобразования атома в двоичное значение.

binary_to_atom

Этот метод используется для преобразования двоичного значения в значение атома.

Эрланг — Карты

Карта — это составной тип данных с переменным количеством ассоциаций ключ-значение. Каждая ассоциация ключ-значение на карте называется парой ассоциации. Ключевые и значимые части пары называются элементами. Количество пар ассоциаций называется размером карты.

Пример того, как можно использовать тип данных Map, показан в следующей программе.

Здесь мы определяем карту M1, которая имеет 2 отображения. Map_size — это встроенная функция, определенная в Erlang, которую можно использовать для определения размера карты.

пример

Live Demo

-module(helloworld). 
-export([start/0]). 

start() -> 
   M1 = #{name=>john,age=>25}, 
   io:fwrite("~w",[map_size(M1)]).

Вывод вышеуказанной программы будет следующим.

Выход

2

Некоторые из других методов, доступных для карт, следующие.

Sr.No. Методы и описание
1

from_list

Этот метод используется для создания карты из списка.

2

находить

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

3

получить

Этот метод используется для получения значения определенного ключа на карте.

4

is_key

Этот метод используется, чтобы определить, определен ли конкретный ключ как ключ на карте.

5

ключи

Этот метод используется для возврата всех ключей с карты.

6

сливаться

Этот метод используется для объединения 2 карт.

7

положил

Этот метод используется для добавления пары ключ-значение на карту.

8

ценности

Этот метод используется для возврата всех значений с карты.

9

Удалить

Этот метод используется для удаления значения ключа с карты.

from_list

Этот метод используется для создания карты из списка.

находить

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

получить

Этот метод используется для получения значения определенного ключа на карте.

is_key

Этот метод используется, чтобы определить, определен ли конкретный ключ как ключ на карте.

ключи

Этот метод используется для возврата всех ключей с карты.

сливаться

Этот метод используется для объединения 2 карт.

положил

Этот метод используется для добавления пары ключ-значение на карту.

ценности

Этот метод используется для возврата всех значений с карты.

Удалить

Этот метод используется для удаления значения ключа с карты.

Эрланг — Кортежи

Кортеж — это составной тип данных с фиксированным числом терминов. Каждый член в кортеже называется элементом. Количество элементов называется размером кортежа.

Пример использования типа данных Tuple показан в следующей программе.

Здесь мы определяем кортеж P, который имеет 3 члена. Tuple_size — это встроенная функция, определенная в Erlang, которая может использоваться для определения размера кортежа.

пример

Live Demo

-module(helloworld). 
-export([start/0]). 

start() ->
   P = {john,24,{june,25}} , 
   io:fwrite("~w",[tuple_size(P)]).

Вывод вышеуказанной программы будет следующим.

Выход

3

Давайте рассмотрим еще несколько операций, которые доступны для кортежей.

Sr.No. Методы и описание
1

is_tuple

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

2

list_to_tuple

Этот метод заключается в преобразовании списка в кортеж.

3

tuple_to_list

Этот метод конвертирует кортеж в список.

is_tuple

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

list_to_tuple

Этот метод заключается в преобразовании списка в кортеж.

tuple_to_list

Этот метод конвертирует кортеж в список.

Эрланг — Рекорды

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

Давайте рассмотрим, как мы можем работать с записями.

Создание записи

Запись создается с использованием идентификатора записи. В этом идентификаторе записи вы указываете различные поля, которые составляют запись. Общий синтаксис и пример приведены ниже.

Синтаксис

record(recordname , {Field1,Field2 ..Fieldn})

параметры

  • имя записи — это имя, данное записи.

  • Field1, Field2 ..Fieldn — это список различных полей, которые составляют запись.

имя записи — это имя, данное записи.

Field1, Field2 ..Fieldn — это список различных полей, которые составляют запись.

Возвращаемое значение

Никто

Например

-module(helloworld). 
-export([start/0]). 
-record(person, {name = "", id}). 

start() -> 
   P = #person{name="John",id = 1}.

В приведенном выше примере показано определение записи с 2 полями, одно из которых является идентификатором, а другое — именем. Кроме того, запись строится следующим образом —

Синтаксис

#recordname {fieldName1 = value1, fieldName2 = value2 .. fieldNameN = valueN}

Где вы присваиваете значения соответствующим полям, когда определен экземпляр записи.

Доступ к значению записи

Для доступа к полям и значениям конкретной записи следует использовать следующий синтаксис.

Синтаксис

#recordname.Fieldname

параметры

  • имя записи — это имя, данное записи.

  • Имя поля — это имя поля, к которому необходимо получить доступ.

имя записи — это имя, данное записи.

Имя поля — это имя поля, к которому необходимо получить доступ.

Возвращаемое значение

Значение, присвоенное полю.

Например

Live Demo

-module(helloworld). 
-export([start/0]). 
-record(person, {name = "", id}). 

start() -> 
   P = #person{name = "John",id = 1}, 
   io:fwrite("~p~n",[P#person.id]), 
   io:fwrite("~p~n",[P#person.name]).

Выход

Вывод вышеуказанной программы выглядит следующим образом.

1
“John”

Обновление значения записи

Обновление значения записи выполняется путем изменения значения в определенном поле и последующего присвоения записи новому имени переменной. Общий синтаксис и пример приведены ниже.

Синтаксис

#recordname.Fieldname = newvalue

параметры

  • имя записи — это имя, данное записи.

  • Имя поля — это имя поля, к которому необходимо получить доступ.

  • newvalue — это новое значение, которое должно быть присвоено полю.

имя записи — это имя, данное записи.

Имя поля — это имя поля, к которому необходимо получить доступ.

newvalue — это новое значение, которое должно быть присвоено полю.

Возвращаемое значение

Новая запись с новыми значениями, присвоенными полям.

Например

Live Demo

-module(helloworld). 
-export([start/0]). 
-record(person, {name = "", id}). 

start() -> 
   P = #person{name = "John",id = 1}, 
   P1 = P#person{name = "Dan"}, 
   
   io:fwrite("~p~n",[P1#person.id]), 
   io:fwrite("~p~n",[P1#person.name]).

Выход

Вывод вышеуказанной программы следующий:

1
“Dan”

Вложенные записи

У Эрланга также есть возможность иметь вложенные записи. В следующем примере показано, как можно создавать эти вложенные записи.

Например

Live Demo

-module(helloworld). 
-export([start/0]). 
-record(person, {name = "", address}). 
-record(employee, {person, id}). 

start() -> 
   P = #employee{person = #person{name = "John",address = "A"},id = 1}, 
   io:fwrite("~p~n",[P#employee.id]).

В приведенном выше примере необходимо отметить следующие вещи:

  • Сначала мы создаем запись о человеке, которая имеет значения полей имени и адреса.

  • Затем мы определяем запись сотрудника, в которой этот человек представлен как поле и дополнительное поле с именем id.

Сначала мы создаем запись о человеке, которая имеет значения полей имени и адреса.

Затем мы определяем запись сотрудника, в которой этот человек представлен как поле и дополнительное поле с именем id.

Выход

Вывод вышеуказанной программы выглядит следующим образом.

1

Эрланг — исключения

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

Обычно, когда в Erlang возникает исключение или ошибка, отображается следующее сообщение.

{"init terminating in do_boot", {undef,[{helloworld,start,[],[]}, 
{init,start_it,1,[]},{init,start_em,1,[]}]}}

Аварийный дамп будет записан в —

erl_crash.dump
init terminating in do_boot ()

В Эрланге есть 3 типа исключений —

  • Ошибка — вызов erlang: error (Reason) завершит выполнение в текущем процессе и включит трассировку стека последних функций, вызываемых с их аргументами, когда вы его перехватываете. Это исключения, которые вызывают ошибки времени выполнения выше.

  • Существует. Существует два вида выходов: «внутренние» и «внешние». Внутренние выходы запускаются вызовом функции exit / 1 и заставляют текущий процесс остановить его выполнение. Внешние выходы вызываются с помощью exit / 2 и связаны с несколькими процессами в параллельном аспекте Erlang.

  • Бросок — Бросок — это класс исключений, используемый в случаях, когда от программиста можно ожидать обработки. По сравнению с выходами и ошибками, они не несут никакого «сбоя этого процесса»! намерение позади них, а скорее они контролируют поток. Поскольку вы используете throw, ожидая, что программист с ними справится, обычно хорошей идеей является документировать их использование в модуле, использующем их.

Ошибка — вызов erlang: error (Reason) завершит выполнение в текущем процессе и включит трассировку стека последних функций, вызываемых с их аргументами, когда вы его перехватываете. Это исключения, которые вызывают ошибки времени выполнения выше.

Существует. Существует два вида выходов: «внутренние» и «внешние». Внутренние выходы запускаются вызовом функции exit / 1 и заставляют текущий процесс остановить его выполнение. Внешние выходы вызываются с помощью exit / 2 и связаны с несколькими процессами в параллельном аспекте Erlang.

Бросок — Бросок — это класс исключений, используемый в случаях, когда от программиста можно ожидать обработки. По сравнению с выходами и ошибками, они не несут никакого «сбоя этого процесса»! намерение позади них, а скорее они контролируют поток. Поскольку вы используете throw, ожидая, что программист с ними справится, обычно хорошей идеей является документировать их использование в модуле, использующем их.

Try … catch — это способ оценить выражение, позволяя вам обрабатывать как успешный случай, так и обнаруженные ошибки.

Общий синтаксис выражения try catch следующий.

Синтаксис

try Expression of 
SuccessfulPattern1 [Guards] -> 
Expression1; 
SuccessfulPattern2 [Guards] -> 
Expression2 

catch 
TypeOfError:ExceptionPattern1 -> 
Expression3; 
TypeOfError:ExceptionPattern2 -> 
Expression4 
end

Выражение между try и of называется защищенным. Это означает, что любые исключения, возникающие в этом вызове, будут обнаружены. Шаблоны и выражения между try … of и catch ведут себя точно так же, как case … of .

Наконец, часть catch — здесь вы можете заменить TypeOfError на ошибку, throw или exit для каждого соответствующего типа, который мы видели в этой главе. Если тип не предоставлен, предполагается бросок.

Ниже приведены некоторые из ошибок и причины ошибок в Erlang —

ошибка Тип ошибки
badarg Плохой аргумент Аргумент имеет неправильный тип данных или неправильно сформирован.
badarith Неверный аргумент в арифметическом выражении.
{Badmatch, V} Оценка выражения соответствия не удалась. Значение V не соответствует.
function_clause Соответствующее предложение функции не найдено при оценке вызова функции.
{Case_clause, V} Соответствующая ветвь не найдена при оценке выражения case. Значение V не соответствует.
если да Не найдена истинная ветвь при вычислении выражения if.
{Try_clause, V} Соответствующая ветвь не найдена при оценке of-секции выражения try. Значение V не соответствует.
UNDEF Функция не может быть найдена при оценке вызова функции.
{Badfun, F} Что-то не так с забавным F
{Badarity, F} Веселье применяется к неправильному количеству аргументов. F описывает веселье и аргументы.
timeout_value Значение тайм-аута в выражении receive..after оценивается как-то иначе, чем целое число или бесконечность.
noproc Попытка связать с несуществующим процессом.

Ниже приведен пример того, как можно использовать эти исключения и как это делается.

  • Первая функция генерирует все возможные типы исключения.

  • Затем мы пишем функцию-оболочку для вызова generate_exception в выражении try … catch.

Первая функция генерирует все возможные типы исключения.

Затем мы пишем функцию-оболочку для вызова generate_exception в выражении try … catch.

пример

-module(helloworld). 
-compile(export_all). 

generate_exception(1) -> a; 
generate_exception(2) -> throw(a); 
generate_exception(3) -> exit(a); 
generate_exception(4) -> {'EXIT', a}; 
generate_exception(5) -> erlang:error(a). 

demo1() -> 
   [catcher(I) || I <- [1,2,3,4,5]]. 
catcher(N) -> 
   try generate_exception(N) of 
      Val -> {N, normal, Val} 
   catch 
      throw:X -> {N, caught, thrown, X}; 
      exit:X -> {N, caught, exited, X}; 
      error:X -> {N, caught, error, X} 
   end. 
      
demo2() -> 
   [{I, (catch generate_exception(I))} || I <- [1,2,3,4,5]]. 
demo3() -> 
   try generate_exception(5) 
   catch 
      error:X -> 
         {X, erlang:get_stacktrace()} 
   end. 
   
lookup(N) -> 
   case(N) of 
      1 -> {'EXIT', a}; 
      2 -> exit(a) 
   end.

Если мы запустим программу как helloworld: demo (). , мы получим следующий вывод —

Выход

[{1,normal,a},
{2,caught,thrown,a},
{3,caught,exited,a},
{4,normal,{'EXIT',a}},
{5,caught,error,a}]

Эрланг — Макросы

Макросы обычно используются для замены встроенного кода. В Erlang макросы определяются с помощью следующих операторов.

  • -определение (константа, замена).
  • -define (Func (Var1, Var2, .., Var), Замена).

Ниже приведен пример макросов, использующих первый синтаксис:

пример

Live Demo

-module(helloworld). 
-export([start/0]). 
-define(a,1). 

start() -> 
   io:fwrite("~w",[?a]).

Из приведенной выше программы вы можете увидеть, что макрос расширяется с помощью ‘?’ условное обозначение. Константа заменяется на месте значением, определенным в макросе.

Выход вышеупомянутой программы будет —

Выход

1

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

пример

Live Demo

-module(helloworld). 
-export([start/0]). 
-define(macro1(X,Y),{X+Y}). 

start() ->
   io:fwrite("~w",[?macro1(1,2)]).

Выход вышеупомянутой программы будет —

Выход

{3}

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

  • undef (Macro) — отменяет определение макроса; после этого вы не можете вызвать макрос.

  • ifdef (Macro)оценивает следующие строки, только если макрос был определен.

  • ifndef (Macro) — оценивает следующие строки, только если Macro не определен.

  • else — разрешено после операторов ifdef или ifndef. Если условие было ложным, операторы, следующие за другим, оцениваются.

  • endif — отмечает конец оператора ifdef или ifndef.

undef (Macro) — отменяет определение макроса; после этого вы не можете вызвать макрос.

ifdef (Macro)оценивает следующие строки, только если макрос был определен.

ifndef (Macro) — оценивает следующие строки, только если Macro не определен.

else — разрешено после операторов ifdef или ifndef. Если условие было ложным, операторы, следующие за другим, оцениваются.

endif — отмечает конец оператора ifdef или ifndef.

При использовании приведенных выше утверждений его следует использовать надлежащим образом, как показано в следующей программе.

-ifdef(<FlagName>).

-define(...).
-else.
-define(...).
-endif.

Erlang — Заголовочные файлы

Заголовочные файлы похожи на включаемые файлы на любом другом языке программирования. Это полезно для разделения модулей на разные файлы и последующего доступа к этим заголовочным файлам в отдельные программы. Чтобы увидеть заголовочные файлы в действии, давайте посмотрим на один из наших предыдущих примеров записей.

Давайте сначала создадим файл с именем user.hrl и добавим следующий код —

-record(person, {name = "", id}).

Теперь в нашем основном файле программы, давайте добавим следующий код —

пример

-module(helloworld). 
-export([start/0]). 
-include("user.hrl"). 

start() -> 
   P = #person{name = "John",id = 1}, 
   io:fwrite("~p~n",[P#person.id]), 
   io:fwrite("~p~n",[P#person.name]).

Как вы можете видеть из приведенной выше программы, мы фактически просто включаем файл user.hrl, который автоматически вставляет в него код –record.

Если вы выполните вышеуказанную программу, вы получите следующий вывод.

Выход

1
“John”

Вы также можете сделать то же самое с макросами, вы можете определить макрос внутри заголовочного файла и ссылаться на него в основном файле. Давайте посмотрим на пример этого —

Давайте сначала создадим файл с именем user.hrl и добавим следующий код —

-define(macro1(X,Y),{X+Y}).

Теперь в нашем основном файле программы, давайте добавим следующий код —

пример

-module(helloworld). 
-export([start/0]). 
-include("user.hrl"). 

start() -> 
   io:fwrite("~w",[?macro1(1,2)]).

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

Выход

{3}

Erlang — Препроцессоры

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

Обычно вам не нужно смотреть на выходные данные препроцессора, но в исключительных случаях (например, при отладке неисправного макроса) вы можете сохранить выходные данные препроцессора. Чтобы увидеть результат предварительной обработки модуля some_module.erl, дайте команду оболочки ОС.

erlc -P some_module.erl

Например, предположим, если у нас был следующий файл кода —

пример

-module(helloworld). 
-export([start/0]). 
-include("user.hrl"). 

start() -> 
   io:fwrite("~w",[?macro1(1,2)]).

И если мы выполнили следующую команду из командной строки —

erlc –P helloworld.erl

Будет создан файл с именем helloworld.P . Если вы откроете этот файл, вы найдете следующее содержимое, которое препроцессор скомпилирует.

-file("helloworld.erl", 1). -module(helloworld).

-export([start/0]).
-file("user.hrl", 1).
-file("helloworld.erl", 3).

start() ->
   io:fwrite("~w", [{1 + 2}]).

Erlang — Pattern Matching

Шаблоны выглядят так же, как термины — они могут быть простыми литералами, такими как атомы и числа, составными, как кортежи и списки, или смесью обоих. Они также могут содержать переменные, которые представляют собой буквенно-цифровые строки, начинающиеся с заглавной буквы или подчеркивания. Специальная «анонимная переменная» _ (подчеркивание) используется, когда вы не заботитесь о сопоставляемом значении и не будете его использовать.

Шаблон соответствует, если он имеет ту же «форму», что и сопоставляемый термин, и встречающиеся атомы совпадают. Например, следующие совпадения успешны —

  • B = 1.
  • 2 = 2.
  • {хорошо, C} = {хорошо, 40}.
  • [H | T] = [1, 2, 3,4].

Обратите внимание, что в четвертом примере труба (|) обозначает начало и конец списка, как описано в Условиях. Также обратите внимание, что левая сторона должна соответствовать правой стороне, что является нормальным случаем для паттернов.

Следующие примеры сопоставления с образцом не удастся.

  • 1 = 2
  • {хорошо, A} = {ошибка, «Не знаю вопроса»}.
  • [H | T] = [].

В случае оператора сопоставления с образцом сбой создает ошибку, и процесс завершается. Как это можно поймать и обработать, описано в разделе «Ошибки». Шаблоны используются для выбора того, какой пункт функции будет выполняться.

Эрланг — Страж

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

Общий синтаксис защитного оператора выглядит следующим образом:

function(parameter) when condition ->

Куда,

  • Функция (параметр) — это объявление функции, которое используется в условии защиты.

  • Параметр — Обычно условие защиты основывается на параметре.

  • Условие — условие, которое должно быть оценено, чтобы увидеть, должна ли функция выполняться или нет.

  • Оператор when должен использоваться, когда указано условие охраны.

Функция (параметр) — это объявление функции, которое используется в условии защиты.

Параметр — Обычно условие защиты основывается на параметре.

Условие — условие, которое должно быть оценено, чтобы увидеть, должна ли функция выполняться или нет.

Оператор when должен использоваться, когда указано условие охраны.

Давайте посмотрим на быстрый пример того, как можно использовать охрану —

пример

Live Demo

-module(helloworld). 
-export([display/1,start/0]). 

display(N) when N > 10 ->   
   io:fwrite("greater then 10"); 
display(N) when N < 10 -> io:fwrite("Less 
   than 10"). 

start() -> 
   display(11).

Следующие вещи должны быть отмечены о приведенном выше примере —

  • Функция отображения определяется вместе с защитой. Первое объявление отображения имеет защиту, когда параметр N больше 10. Поэтому, если параметр больше 10, эта функция будет вызвана.

  • Функция отображения определяется снова, но на этот раз с защитой менее 10. Таким образом, вы можете определить одну и ту же функцию несколько раз, каждая с отдельным условием защиты.

Функция отображения определяется вместе с защитой. Первое объявление отображения имеет защиту, когда параметр N больше 10. Поэтому, если параметр больше 10, эта функция будет вызвана.

Функция отображения определяется снова, но на этот раз с защитой менее 10. Таким образом, вы можете определить одну и ту же функцию несколько раз, каждая с отдельным условием защиты.

Вывод вышеуказанной программы будет следующим:

Выход

greater than 10

Условия охраны могут также использоваться для операторов if else и case . Посмотрим, как мы можем проводить охранные операции по этим заявлениям.

Охранники для утверждений «если»

Защитные элементы также можно использовать для операторов if, так что последовательность выполняемых операторов основана на условии защиты. Посмотрим, как нам этого добиться.

пример

Live Demo

-module(helloworld). 
-export([start/0]). 

start() -> 
   N = 9, 
   if 
      N > 10 -> 
         io:fwrite("N is greater than 10"); 
      true -> 
         io:fwrite("N is less than 10") 
   end.

Следующие вещи должны быть отмечены о приведенном выше примере —

  • Функция guard используется вместе с оператором if. Если функция защиты оценивается как истина, то выводится сообщение «N больше 10».

  • Если функция защиты оценивается как ложная, отображается сообщение «N меньше 10».

Функция guard используется вместе с оператором if. Если функция защиты оценивается как истина, то выводится сообщение «N больше 10».

Если функция защиты оценивается как ложная, отображается сообщение «N меньше 10».

Вывод вышеуказанной программы будет следующим:

Выход

N is less than 10

Охранники для «case» заявлений

Защитные ограждения также могут использоваться для выписок по делу, поэтому последовательность выполняемых заявлений основана на условии охраны. Посмотрим, как нам этого добиться.

пример

Live Demo

-module(helloworld). 
-export([start/0]). 

start() -> 
   A = 9, 
   case A of {A} when A>10 -> 
      io:fwrite("The value of A is greater than 10"); _ -> 
      io:fwrite("The value of A is less than 10") 
   end.

Следующие вещи должны быть отмечены о приведенном выше примере —

  • Функция guard используется вместе с оператором case. Если функция защиты оценивается как истина, то отображается сообщение «Значение А больше 10».

  • Если функция защиты оценивает что-либо еще, то выводится сообщение «Значение A меньше 10».

Функция guard используется вместе с оператором case. Если функция защиты оценивается как истина, то отображается сообщение «Значение А больше 10».

Если функция защиты оценивает что-либо еще, то выводится сообщение «Значение A меньше 10».

Вывод вышеуказанной программы будет следующим:

Выход

The value of A is less than 10

Несколько условий охраны

Для функции также могут быть указаны несколько условий защиты. Общий синтаксис защитного оператора с несколькими защитными условиями приведен ниже —

function(parameter) when condition1 , condition1 , .. conditionN ->

Куда,

  • Функция (параметр) — это объявление функции, которое использовало условие защиты.

  • Параметр — Обычно условие защиты основывается на параметре.

  • условие1, условие1, .. условиеN — это несколько защитных условий, которые применяются к функциям.

  • Оператор when должен использоваться, когда указано условие охраны.

Функция (параметр) — это объявление функции, которое использовало условие защиты.

Параметр — Обычно условие защиты основывается на параметре.

условие1, условие1, .. условиеN — это несколько защитных условий, которые применяются к функциям.

Оператор when должен использоваться, когда указано условие охраны.

Давайте посмотрим на быстрый пример того, как можно использовать несколько охранников —

пример

Live Demo

-module(helloworld). 
-export([display/1,start/0]). 

display(N) when N > 10 , is_integer(N) -> 
   io:fwrite("greater then 10"); 
display(N) when N < 10 -> 
   io:fwrite("Less than 10"). 
   
start() -> 
   display(11).

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

  • Вы заметите, что для первого объявления функции отображения, в дополнение к условию для N> 10, также указано условие для is_integer . Таким образом, только если значение N является целым числом и больше 10, эта функция будет выполняться.

Вы заметите, что для первого объявления функции отображения, в дополнение к условию для N> 10, также указано условие для is_integer . Таким образом, только если значение N является целым числом и больше 10, эта функция будет выполняться.

Вывод вышеуказанной программы будет следующим:

Выход

Greater than 10

Эрланг — BIFS

BIF — это функции, встроенные в Erlang. Обычно они выполняют задачи, которые невозможно программировать на Erlang. Например, невозможно превратить список в кортеж или найти текущее время и дату. Для выполнения такой операции мы вызываем BIF.

Давайте рассмотрим пример использования BIF —

пример

Live Demo

-module(helloworld). 
-export([start/0]). 

start() ->   
   io:fwrite("~p~n",[tuple_to_list({1,2,3})]), 
   io:fwrite("~p~n",[time()]).

Следующие вещи должны быть отмечены о приведенном выше примере —

  • В первом примере мы используем BIF с именем tuple_to_list для преобразования кортежа в список.

  • Во второй функции BIF мы используем функцию времени для вывода системного времени.

В первом примере мы используем BIF с именем tuple_to_list для преобразования кортежа в список.

Во второй функции BIF мы используем функцию времени для вывода системного времени.

Вывод вышеуказанной программы будет следующим:

Выход

[1,2,3]
{10,54,56}

Давайте посмотрим на некоторые из дополнительных функций BIF, доступных в Erlang.

Sr.No. BIF Функции и описание
1

Дата

Этот метод возвращает текущую системную дату.

2

byte_size

Этот метод возвращает количество байтов, содержащихся в цепочке битов.

3

элемент

Метод возвращает N-й элемент в кортеже.

4

поплавок

Этот метод возвращает значение с плавающей точкой определенного числа.

5

получить

Метод возвращает словарь процесса в виде списка.

6

положил

Этот метод используется для помещения пары ключ-значение в словарь процесса.

7

местное время

Этот метод используется для определения локальной даты и времени в системе.

8

объем памяти

Возвращает список, содержащий информацию о памяти, динамически выделяемой эмулятором Эрланга.

9

сейчас

Этот метод возвращает кортеж {MegaSecs, Secs, MicroSecs}, который является временем, прошедшим с 00:00 по Гринвичу, 1 января 1970 года.

10

порты

Возвращает список всех портов на локальном узле

11

процессы

Возвращает список идентификаторов процессов, соответствующих всем процессам, в настоящее время существующим на локальном узле.

12

universaltime

Возвращает текущую дату и время в соответствии с всемирным координированным временем (UTC).

Дата

Этот метод возвращает текущую системную дату.

byte_size

Этот метод возвращает количество байтов, содержащихся в цепочке битов.

элемент

Метод возвращает N-й элемент в кортеже.

поплавок

Этот метод возвращает значение с плавающей точкой определенного числа.

получить

Метод возвращает словарь процесса в виде списка.

положил

Этот метод используется для помещения пары ключ-значение в словарь процесса.

местное время

Этот метод используется для определения локальной даты и времени в системе.

объем памяти

Возвращает список, содержащий информацию о памяти, динамически выделяемой эмулятором Эрланга.

сейчас

Этот метод возвращает кортеж {MegaSecs, Secs, MicroSecs}, который является временем, прошедшим с 00:00 по Гринвичу, 1 января 1970 года.

порты

Возвращает список всех портов на локальном узле

процессы

Возвращает список идентификаторов процессов, соответствующих всем процессам, в настоящее время существующим на локальном узле.

universaltime

Возвращает текущую дату и время в соответствии с всемирным координированным временем (UTC).

Эрланг — Двоичные файлы

Используйте структуру данных, называемую двоичным файлом, для хранения больших объемов необработанных данных. Двоичные файлы хранят данные гораздо более эффективным образом, чем списки или кортежи, а система времени выполнения оптимизирована для эффективного ввода и вывода двоичных файлов.

Двоичные файлы записываются и печатаются как последовательности целых чисел или строк, заключенные в двойные числа, меньшие или большие скобок.

Ниже приведен пример двоичных файлов в Erlang —

пример

Live Demo

-module(helloworld). 
-export([start/0]). 

start() -> 
   io:fwrite("~p~n",[<<5,10,20>>]), 
   io:fwrite("~p~n",[<<"hello">>]).

Когда мы запустим вышеуказанную программу, мы получим следующий результат.

Выход

<<5,10,20>>
<<"hello">>

Давайте посмотрим на функции Erlang, которые доступны для работы с двоичными файлами —

Sr.No. Методы и описание
1

list_to_binary

Этот метод используется для преобразования существующего списка в список двоичных файлов.

2

split_binary

Этот метод используется для разделения двоичного списка на основе указанной позиции индекса.

3

term_to_binary

Этот метод используется для преобразования термина в двоичный файл.

4

is_binary

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

5

binary_part

Этот метод используется для извлечения части двоичной строки

6

binary_to_float

Этот метод используется для преобразования двоичного значения в значение с плавающей запятой.

7

binary_to_integer

Этот метод используется для преобразования двоичного значения в целочисленное значение.

8

binary_to_list

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

9

binary_to_atom

Этот метод используется для преобразования двоичного значения в атом.

list_to_binary

Этот метод используется для преобразования существующего списка в список двоичных файлов.

split_binary

Этот метод используется для разделения двоичного списка на основе указанной позиции индекса.

term_to_binary

Этот метод используется для преобразования термина в двоичный файл.

is_binary

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

binary_part

Этот метод используется для извлечения части двоичной строки

binary_to_float

Этот метод используется для преобразования двоичного значения в значение с плавающей запятой.

binary_to_integer

Этот метод используется для преобразования двоичного значения в целочисленное значение.

binary_to_list

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

binary_to_atom

Этот метод используется для преобразования двоичного значения в атом.

Эрланг — Развлечения

Funs используются для определения анонимных функций в Erlang. Общий синтаксис анонимной функции приведен ниже —

Синтаксис

F = fun (Arg1, Arg2, ... ArgN) ->
   ...
End

куда

  • F — это имя переменной, назначенной анонимной функции.

  • Arg1, Arg2, … ArgN — это аргументы, которые передаются анонимной функции.

F — это имя переменной, назначенной анонимной функции.

Arg1, Arg2, … ArgN — это аргументы, которые передаются анонимной функции.

В следующем примере показано, как можно использовать анонимную функцию.

пример

Live Demo

-module(helloworld). 
-export([start/0]). 

start() -> 
   A = fun() -> io:fwrite("Hello") end, 
   A().

Следующие вещи необходимо отметить о вышеупомянутой программе.

  • Анонимная функция назначается переменной A.

  • Анонимная функция через переменную A ().

Анонимная функция назначается переменной A.

Анонимная функция через переменную A ().

Когда мы запустим вышеуказанную программу, мы получим следующий результат.

“Hello”

Другой пример анонимной функции заключается в следующем, но это с использованием параметров.

Live Demo

-module(helloworld). 
-export([start/0]). 

start() -> 
   A = fun(X) -> 
      io:fwrite("~p~n",[X]) 
      end, 
   A(5).

Когда мы запустим вышеуказанную программу, мы получим следующий результат.

Выход

5

Использование переменных

Функция Anonymous имеет возможность доступа к переменным, которые находятся за пределами области действия анонимной функции. Давайте посмотрим на пример этого —

пример

Live Demo

-module(helloworld). 
-export([start/0]). 

start() -> 
   B = 6, 
   A = fun(X) -> 
      io:fwrite("~p~n",[X]), 
      io:fwrite("~p~n",[B]) 
      end, 
   A(5).

Следующие вещи необходимо отметить о вышеупомянутой программе.

  • Переменная B находится вне области действия анонимной функции.

  • Анонимная функция все еще может обращаться к переменной, определенной в глобальной области видимости.

Переменная B находится вне области действия анонимной функции.

Анонимная функция все еще может обращаться к переменной, определенной в глобальной области видимости.

Когда мы запустим вышеуказанную программу, мы получим следующий результат.

Выход

5

6

Функции внутри функций

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

пример

Live Demo

-module(helloworld). 
-export([start/0]). 

start() -> 
   Adder = fun(X) -> fun(Y) -> io:fwrite("~p~n",[X + Y]) end end, 
   A = Adder(6), 
   A(10).

Следующие вещи необходимо отметить о вышеупомянутой программе.

  • Adder — функция высшего порядка, определенная как fun (X).

  • Функция Adder fun (X) имеет ссылку на другую функцию fun (Y).

Adder — функция высшего порядка, определенная как fun (X).

Функция Adder fun (X) имеет ссылку на другую функцию fun (Y).

Когда мы запустим вышеуказанную программу, мы получим следующий результат.

Выход

16

Эрланг — Процессы

Гранулярность параллелизма в Erlang — это процесс. Процесс — это действие / задача, которая выполняется одновременно и не зависит от других процессов. Эти процессы в Erlang отличаются от процессов и потоков, с которыми знакомы большинство людей. Процессы Erlang легки, работают в (памяти) изолированно от других процессов и планируются виртуальной машиной Erlang (VM). Время создания процесса очень мало, объем памяти только что созданного процесса очень мал, и на одной виртуальной машине Erlang могут работать миллионы процессов.

Процесс создается с помощью метода spawn. Общий синтаксис метода приведен ниже.

Синтаксис

spawn(Module, Name, Args)

параметры

  • Модуль — это предопределенное значение атома, которое должно быть? MODULE.

  • Имя — это имя функции, которая вызывается при определении процесса.

  • Args — это аргументы, которые необходимо отправить в функцию.

Модуль — это предопределенное значение атома, которое должно быть? MODULE.

Имя — это имя функции, которая вызывается при определении процесса.

Args — это аргументы, которые необходимо отправить в функцию.

Возвращаемое значение

Возвращает идентификатор процесса нового созданного процесса.

Например

Пример метода spawn показан в следующей программе.

Live Demo

-module(helloworld). 
-export([start/0, call/2]). 

call(Arg1, Arg2) -> 
   io:format("~p ~p~n", [Arg1, Arg2]). 
start() -> 
   Pid = spawn(?MODULE, call, ["hello", "process"]), 
   io:fwrite("~p",[Pid]).

Следующие вещи необходимо отметить о вышеупомянутой программе.

  • Функция с именем call определена и будет использоваться для создания процесса.

  • Метод spawn вызывает функцию call с параметрами hello и process.

Функция с именем call определена и будет использоваться для создания процесса.

Метод spawn вызывает функцию call с параметрами hello и process.

Выход

Когда мы запустим вышеуказанную программу, мы получим следующий результат.

<0.29.0>"hello" "process"

Теперь давайте посмотрим на другие функции, которые доступны с процессами.

Sr.No. Методы и описание
1

is_pid

Этот метод используется, чтобы определить, существует ли идентификатор процесса.

2

is_process_alive

Это называется is_process_alive (Pid). Pid должен ссылаться на процесс в локальном узле.

3

pid_to_list

Он преобразует идентификатор процесса в список.

4

зарегистрированный

Возвращает список с именами всех зарегистрированных процессов.

5

сам

Один из наиболее часто используемых BIF, возвращает pid вызывающих процессов.

6

регистр

Это используется для регистрации процесса в системе.

7

где

Это называется whereis (Имя). Возвращает pid процесса, который зарегистрирован под именем.

8

разрегистрировать

Это используется для отмены регистрации процесса в системе.

is_pid

Этот метод используется, чтобы определить, существует ли идентификатор процесса.

is_process_alive

Это называется is_process_alive (Pid). Pid должен ссылаться на процесс в локальном узле.

pid_to_list

Он преобразует идентификатор процесса в список.

зарегистрированный

Возвращает список с именами всех зарегистрированных процессов.

сам

Один из наиболее часто используемых BIF, возвращает pid вызывающих процессов.

регистр

Это используется для регистрации процесса в системе.

где

Это называется whereis (Имя). Возвращает pid процесса, который зарегистрирован под именем.

разрегистрировать

Это используется для отмены регистрации процесса в системе.

Erlang — электронная почта

Чтобы отправить электронное письмо с использованием Erlang, вам нужно использовать пакет, доступный на github для того же. Ссылка на github — https://github.com/Vagabond/gen_smtp

Эта ссылка содержит утилиту smtp, которую можно использовать для отправки электронной почты из приложения Erlang. Следуйте инструкциям, чтобы иметь возможность отправить электронное письмо от Erlang

Шаг 1 — Загрузите файлы erl с сайта github . Файлы должны быть загружены в каталог, где находится ваше приложение helloworld.erl .

Шаг 2 — Скомпилируйте все файлы, связанные с SMTP, показанные в следующем списке, с помощью команды erlc . Следующие файлы должны быть скомпилированы.

  • smtp_util
  • gen_smtp_client
  • gen_smtp_server
  • gen_smtp_server_session
  • binstr
  • gen_smtp_application
  • разъем

Шаг 3 — Следующий код может быть написан для отправки электронной почты с помощью SMTP.

пример

-module(helloworld). 
-export([start/0]). 

start() -> 
   gen_smtp_client:send({"sender@gmail.com", ["receiver@gmail.com"], "Subject: testing"},
   
   [{relay, "smtp.gmail.com"}, {ssl, true}, {username, "sender@gmail.com"}, 
      {password, "senderpassword"}]).

Следующие вещи должны быть отмечены о вышеупомянутой программе

  • Вышеупомянутая функция smtp используется вместе с сервером smtp, доступным от Google.

  • Так как мы хотели отправить с использованием безопасного smtp, мы указываем параметр ssl как true.

  • Вы должны указать реле как smtp.gmail.com .

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

Вышеупомянутая функция smtp используется вместе с сервером smtp, доступным от Google.

Так как мы хотели отправить с использованием безопасного smtp, мы указываем параметр ssl как true.

Вы должны указать реле как smtp.gmail.com .

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

После того, как вы настроите все вышеперечисленные параметры и запустите программу, получатель успешно получит электронное письмо.

Erlang — Базы данных

Erlang имеет возможность подключения к традиционным базам данных, таким как SQL Server и Oracle. Erlang имеет встроенную библиотеку odbc, которую можно использовать для работы с базами данных.

Подключение к базе данных

В нашем примере мы собираемся использовать Microsoft SQL Server. Перед подключением к базе данных Microsoft SQL Server убедитесь, что следующие указатели проверены.

  • Вы создали базу данных TESTDB.

  • Вы создали таблицу EMPLOYEE в TESTDB.

  • В этой таблице есть поля FIRST_NAME, LAST_NAME, AGE, SEX и INCOME.

  • Идентификатор пользователя «testuser» и пароль «test123» установлены для доступа к TESTDB.

  • Убедитесь, что вы создали ODBC DSN с именем usersqlserver, который создает ODBC-соединение с базой данных.

Вы создали базу данных TESTDB.

Вы создали таблицу EMPLOYEE в TESTDB.

В этой таблице есть поля FIRST_NAME, LAST_NAME, AGE, SEX и INCOME.

Идентификатор пользователя «testuser» и пароль «test123» установлены для доступа к TESTDB.

Убедитесь, что вы создали ODBC DSN с именем usersqlserver, который создает ODBC-соединение с базой данных.

Установление соединения

Чтобы установить соединение с базой данных, можно использовать следующий пример кода.

пример

-module(helloworld). 
-export([start/0]). 

start() ->
   odbc:start(), 
   {ok, Ref} = odbc:connect("DSN = usersqlserver;UID = testuser;PWD = test123", []), 
   io:fwrite("~p",[Ref]).

Вывод вышеуказанной программы следующий:

Выход

<0.33.0>

Следующие вещи необходимо отметить о вышеупомянутой программе.

  • Метод start библиотеки odbc используется для указания начала операции базы данных.

  • Для подключения требуется DSN, имя пользователя и пароль для подключения.

Метод start библиотеки odbc используется для указания начала операции базы данных.

Для подключения требуется DSN, имя пользователя и пароль для подключения.

Создание таблицы базы данных

Следующим шагом после подключения к базе данных является создание таблиц в нашей базе данных. В следующем примере показано, как создать таблицу в базе данных, используя Erlang.

пример

-module(helloworld). 
-export([start/0]). 

start() -> 
   odbc:start(), 
   {ok, Ref} = odbc:connect("DSN = usersqlserver; UID = testuser;PWD = test123, []), 
   odbc:sql_query(Ref, "CREATE TABLE EMPLOYEE (FIRSTNAME char varying(20), 
   LASTNAME char varying(20), AGE integer, SEX char(1), INCOME integer)")

Если вы сейчас проверите базу данных, вы увидите, что будет создана таблица EMPLOYEE .

Вставка записи в базу данных

Это необходимо, когда вы хотите создать свои записи в таблице базы данных.

В следующем примере будет вставлена ​​запись в таблицу сотрудников. Если таблица успешно обновлена, запись и инструкция вернут значение обновленной записи и количество записей, которые были обновлены.

пример

-module(helloworld). 
-export([start/0]). 

start() -> 
   odbc:start(), 
   {ok, Ref} = odbc:connect("DSN = usersqlserver; UID = testuser;PWD = test123", []), 
   io:fwrite("~p",[odbc:sql_query(Ref, 
   "INSERT INTO EMPLOYEE VALUES('Mac', 'Mohan', 20, 'M', 2000)")]).

Выход вышеупомянутой программы будет —

Выход

{updated,1}

Извлечение записей из базы данных

Erlang также имеет возможность извлекать записи из базы данных. Это делается с помощью метода sql_query .

Пример показан в следующей программе —

пример

-module(helloworld). 
-export([start/0]). 

start() ->
   odbc:start(), 
   {ok, Ref} = odbc:connect("DSN = usersqlserver; UID = testuser;PWD = test123", []), 
   io:fwrite("~p",[odbc:sql_query(Ref, "SELECT * FROM EMPLOYEE") ]).

Вывод вышеуказанной программы будет следующим:

Выход

{selected,["FIRSTNAME","LASTNAME","AGE","SEX","INCOME"],
[{"Mac","Mohan",20,"M",2000}]}

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

Выборка записей из базы данных на основе параметров

Erlang также имеет возможность извлекать записи из базы данных на основе определенных критериев фильтрации.

Пример таков:

пример

-module(helloworld). 
-export([start/0]). 

start() -> 
   odbc:start(), 
   {ok, Ref} = odbc:connect("DSN=usersqlserver; UID=testuser;PWD=test123", []), 
   io:fwrite("~p",[ odbc:param_query(Ref, "SELECT * FROM EMPLOYEE WHERE SEX=?", 
   [{{sql_char, 1}, ["M"]}])]).

Выход вышеупомянутой программы будет —

Выход

{selected,["FIRSTNAME","LASTNAME","AGE","SEX","INCOME"],
         [{"Mac","Mohan",20,"M",2000}]}

Обновление записей из базы данных

Erlang также имеет возможность обновлять записи из базы данных.

Примером того же является следующее —

пример

-module(helloworld). 
-export([start/0]). 

start() -> 
   odbc:start(), 
   {ok, Ref} = odbc:connect("DSN = usersqlserver; UID = testuser;PWD = test123", []), 
   
   io:fwrite("~p",[ odbc:sql_query(Ref, "
      UPDATE EMPLOYEE SET AGE = 5 WHERE INCOME= 2000")]).

Выход вышеупомянутой программы будет —

Выход

{updated,1}

Удаление записей из базы данных

Erlang также имеет возможность удалять записи из базы данных.

Примером того же является следующее —

пример

-module(helloworld). 
-export([start/0]). 

start() -> 
   odbc:start(), 
   {ok, Ref} = odbc:connect("DSN = usersqlserver; UID = testuser;PWD = test123", []), 
   io:fwrite("~p",[ odbc:sql_query(Ref, "DELETE EMPLOYEE WHERE INCOME= 2000")]).

Вывод вышеуказанной программы будет следующим:

Выход

{updated,1}

Структура таблицы

Эрланг также имеет возможность описать структуру таблицы.

Пример таков:

пример

-module(helloworld). 
-export([start/0]). 

start() -> 
   odbc:start(), 
   {ok, Ref} = odbc:connect("DSN = usersqlserver; UID = testuser;PWD = test123", []), 
   io:fwrite("~p",[odbc:describe_table(Ref, "EMPLOYEE")]).

Вывод вышеуказанной программы будет следующим:

Выход

{ok,[{"FIRSTNAME",{sql_varchar,20}},
   {"LASTNAME",{sql_varchar,20}},
   {"AGE",sql_integer},
   {"SEX",{sql_char,1}},
   {"INCOME",sql_integer}]}

Количество записей

Erlang также имеет возможность извлекать общее количество записей в таблице.

Пример того же самого показан в следующей программе.

пример

-module(helloworld). 
-export([start/0]). 

start() ->
   odbc:start(), 
   {ok, Ref} = odbc:connect("DSN = usersqlserver; UID = sa;PWD = demo123", []), 
   io:fwrite("~p",[odbc:select_count(Ref, "SELECT * FROM EMPLOYEE")]).

Выход вышеупомянутой программы будет —

{ok,1}

Эрланг — Порты

В Erlang порты используются для связи между различными программами. Сокет — это конечная точка связи, которая позволяет компьютерам обмениваться данными через Интернет с использованием Интернет-протокола (IP).

Типы протоколов, используемых в портах

Для связи доступно 2 типа протоколов. Один — UDP, а другой — TCP. UDP позволяет приложениям отправлять друг другу короткие сообщения (так называемые датаграммы), но нет гарантии доставки этих сообщений. Они также могут прибыть из строя. TCP, с другой стороны, обеспечивает надежный поток байтов, которые доставляются в порядке, пока установлено соединение.

Давайте рассмотрим простой пример открытия порта с использованием UDP.

пример

Live Demo

 модуль (HelloWorld). 
 -export ([старт / 0]). 

 start () -> 
    {ok, Socket} = gen_udp: open (8789), 
    Io: FWRITE ( "~ р", [гнездо]).

Следующие вещи должны быть отмечены о вышеупомянутой программе

  • Gen_udp содержит модули в Erlang, используемые для связи UDP.

  • Здесь 8789 — номер порта, который открывается в Erlang. Вы должны убедиться, что этот номер порта доступен и может использоваться.

Gen_udp содержит модули в Erlang, используемые для связи UDP.

Здесь 8789 — номер порта, который открывается в Erlang. Вы должны убедиться, что этот номер порта доступен и может использоваться.

Выход вышеуказанной программы —

#Port<0.376>

Отправка сообщения в порт

После открытия порта на него можно отправить сообщение. Это делается с помощью метода отправки. Давайте посмотрим на синтаксис и следующий пример.

Синтаксис

send(Socket, Address, Port, Packet)

параметры

  • Сокет — это сокет, созданный с помощью команды gen_udp: open.

  • Адрес — это адрес компьютера, на который должно быть отправлено сообщение.

  • порт — это номер порта, на который необходимо отправить сообщение.

  • Пакет — это детали пакета или сообщения, которые необходимо отправить.

Сокет — это сокет, созданный с помощью команды gen_udp: open.

Адрес — это адрес компьютера, на который должно быть отправлено сообщение.

порт — это номер порта, на который необходимо отправить сообщение.

Пакет — это детали пакета или сообщения, которые необходимо отправить.

Возвращаемые значения

Сообщение «OK» возвращается, если сообщение было отправлено правильно.

Например

Live Demo

-module(helloworld). 
-export([start/0]). 

start() ->
   {ok, Socket} = gen_udp:open(8789), 
   io:fwrite("~p",[Socket]), 
   io:fwrite("~p",[gen_udp:send 
   (Socket,"localhost",8789,"Hello")]).

Выход

Вывод вышеуказанной программы будет следующим.

#Port<0.376>ok

Получение сообщения в порту

После открытия порта на порт также можно получить сообщение. Это делается с помощью метода recv . Давайте посмотрим на синтаксис и следующий пример.

Синтаксис

recv(Socket, length)

параметры

  • Сокет — это сокет, созданный с помощью команды gen_udp: open.

  • Длина — это длина сообщения, которое необходимо получить.

Сокет — это сокет, созданный с помощью команды gen_udp: open.

Длина — это длина сообщения, которое необходимо получить.

Возвращаемые значения

Сообщение «OK» возвращается, если сообщение было отправлено правильно.

Например

-module(helloworld). 
-export([start/0]). 

start() ->
   {ok, Socket} = gen_udp:open(8789), 
   io:fwrite("~p",[Socket]), 
   io:fwrite("~p",[gen_udp:send(Socket,"localhost",8789,"Hello")]),
   io:fwrite("~p",[gen_udp:recv(Socket, 20)]).

Полная программа

Теперь очевидно, что в одной и той же программе нельзя отправлять и получать одно и то же сообщение. Вы должны определить их в разных программах. Итак, давайте создадим следующий код, который создает серверный компонент, который слушает сообщения, и клиентский компонент, который отправляет сообщения.

пример

Live Demo

-module(helloworld). 
-export([start/0,client/1]). 

start() -> 
   spawn(fun() -> server(4000) end).

server(Port) ->
   {ok, Socket} = gen_udp:open(Port, [binary, {active, false}]), 
   io:format("server opened socket:~p~n",[Socket]), 
   loop(Socket). 

loop(Socket) ->
   inet:setopts(Socket, [{active, once}]), 
   receive 
      {udp, Socket, Host, Port, Bin} -> 
      io:format("server received:~p~n",[Bin]), 
      gen_udp:send(Socket, Host, Port, Bin), 
      loop(Socket) 
   end. 

client(N) -> 
   {ok, Socket} = gen_udp:open(0, [binary]), 
   io:format("client opened socket=~p~n",[Socket]), 
   ok = gen_udp:send(Socket, "localhost", 4000, N), Value = receive 
      {udp, Socket, _, _, Bin} ->
         io:format("client received:~p~n",[Bin]) after 2000 ->
      0 
   end, 
   
gen_udp:close(Socket), 
Value.

Следующие вещи необходимо отметить о вышеупомянутой программе.

  • Мы определяем 2 функции, первая — серверная. Это будет использоваться для прослушивания порта 4000. Второй — это клиент, который будет использоваться для отправки сообщения «Hello» компоненту сервера.

  • Цикл приема используется для чтения сообщений, отправленных в цикле определения.

Мы определяем 2 функции, первая — серверная. Это будет использоваться для прослушивания порта 4000. Второй — это клиент, который будет использоваться для отправки сообщения «Hello» компоненту сервера.

Цикл приема используется для чтения сообщений, отправленных в цикле определения.

Выход

Теперь вам нужно запустить программу из 2 окон. Первое окно будет использоваться для запуска серверного компонента путем запуска следующего кода в окне командной строки erl .

helloworld:start().

Это отобразит следующий вывод в окне командной строки.

server opened socket:#Port<0.2314>

Теперь во втором окне командной строки erl выполните следующую команду.

Helloworld:client(“<<Hello>>”).

Когда вы вводите эту команду, в первом окне командной строки будут отображаться следующие выходные данные.

server received:<<"Hello">>

Erlang — распределенное программирование

Распределенные программы — это те программы, которые предназначены для работы в сетях компьютеров и могут координировать свои действия только путем передачи сообщений.

Есть ряд причин, по которым мы могли бы захотеть писать распределенные приложения. Вот некоторые из них.

  • Производительность. Мы можем ускорить выполнение наших программ, организовав параллельное выполнение разных частей программы на разных компьютерах.

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

  • Масштабируемость. По мере того, как мы расширяем приложение, рано или поздно мы исчерпаем возможности даже самой мощной машины. На этом этапе мы должны добавить больше машин для увеличения мощности. Добавление нового компьютера должно быть простой операцией, которая не требует больших изменений в архитектуре приложения.

Производительность. Мы можем ускорить выполнение наших программ, организовав параллельное выполнение разных частей программы на разных компьютерах.

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

Масштабируемость. По мере того, как мы расширяем приложение, рано или поздно мы исчерпаем возможности даже самой мощной машины. На этом этапе мы должны добавить больше машин для увеличения мощности. Добавление нового компьютера должно быть простой операцией, которая не требует больших изменений в архитектуре приложения.

Центральным понятием в распределенном Erlang является узел. Узел является автономным.

Система Erlang содержит полную виртуальную машину с собственным адресным пространством и собственным набором процессов.

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

Sr.No. Методы и описание
1

порождать

Это используется для создания нового процесса и его инициализации.

2

узел

Это используется для определения значения узла, на котором должен выполняться процесс.

3

порождение на узле

Это используется для создания нового процесса на узле.

4

является живым

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

5

spawnlink

Это используется для создания новой связи процесса на узле.

порождать

Это используется для создания нового процесса и его инициализации.

узел

Это используется для определения значения узла, на котором должен выполняться процесс.

порождение на узле

Это используется для создания нового процесса на узле.

является живым

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

spawnlink

Это используется для создания новой связи процесса на узле.

Эрланг — ОТП

OTP расшифровывается как Open Telecom Platform. Это операционная система приложения и набор библиотек и процедур, используемых для создания крупномасштабных отказоустойчивых распределенных приложений. Если вы хотите программировать свои собственные приложения с использованием OTP, то основная идея, которую вы найдете очень полезной, — это поведение OTP. Поведение инкапсулирует общие поведенческие паттерны — воспринимайте его как структуру приложения, параметризованную модулем обратного вызова.

Мощность OTP зависит от таких свойств, как отказоустойчивость, масштабируемость, обновление динамического кода и т. Д., Которые могут быть предоставлены самим поведением. Итак, первая базовая концепция заключается в создании серверного компонента, который имитирует основы среды OTP, давайте рассмотрим следующий пример.

пример

-module(server). 
-export([start/2, rpc/2]). 

start(Name, Mod) -> 
   register(Name, spawn(fun() -> loop(Name, Mod, Mod:init()) end)). 
rpc(Name, Request) -> 
   Name ! {self(), Request}, 
   receive 
      {Name, Response} -> Response 
   end. 
   
loop(Name, Mod, State) ->
   receive 
      {From, Request} ->
         {Response, State1} = Mod:handle(Request, State), 
         From ! {Name, Response}, 
         loop(Name, Mod, State1) 
   end.

Следующие вещи должны быть отмечены о вышеупомянутой программе —

  • Процесс, если он зарегистрирован в системе с использованием функции регистрации.

  • Процесс порождает функцию цикла, которая обрабатывает обработку.

Процесс, если он зарегистрирован в системе с использованием функции регистрации.

Процесс порождает функцию цикла, которая обрабатывает обработку.

Теперь давайте напишем клиентскую программу, которая будет использовать серверную программу.

пример

-module(name_server). 
-export([init/0, add/2, whereis/1, handle/2]). 
-import(server1, [rpc/2]). 

add(Name, Place) -> rpc(name_server, {add, Name, Place}). 
whereis(Name) -> rpc(name_server, {whereis, Name}). 

init() -> dict:new().
handle({add, Name, Place}, Dict) -> {ok, dict:store(Name, Place, Dict)}; 
handle({whereis, Name}, Dict) -> {dict:find(Name, Dict), Dict}.

Этот код фактически выполняет две задачи. Он служит в качестве модуля обратного вызова, который вызывается из кода серверной платформы, и в то же время содержит подпрограммы взаимодействия, которые будут вызываться клиентом. Обычное соглашение OTP состоит в том, чтобы объединить обе функции в одном модуле.

Итак, вот как нужно запустить вышеуказанную программу:

В erl сначала запустите серверную программу, выполнив следующую команду.

server(name_server,name_server)

Вы получите следующий вывод —

Выход

true

Затем выполните следующую команду

name_server.add(erlang,”Tutorialspoint”).

Вы получите следующий вывод —

Выход

Ok

Затем выполните следующую команду —

name_server.whereis(erlang).

Вы получите следующий вывод —

Выход

{ok,"Tutorialspoint"}

Erlang — параллелизм

Параллельное программирование в Erlang должно иметь следующие основные принципы или процессы.

Список включает в себя следующие принципы —

piD = spawn (Fun)

Создает новый параллельный процесс, который оценивает Fun. Новый процесс выполняется параллельно с вызывающей стороной. Пример таков:

пример

Live Demo

-module(helloworld). 
-export([start/0]). 

start() ->
   spawn(fun() -> server("Hello") end). 

server(Message) ->
   io:fwrite("~p",[Message]).

Выход вышеуказанной программы —

Выход

“Hello”

Пид! Сообщение

Посылает сообщение процессу с идентификатором Pid. Отправка сообщения асинхронная. Отправитель не ждет, а продолжает то, что делал. ‘!’ называется оператором отправки.

Пример таков:

пример

Live Demo

-module(helloworld). 
-export([start/0]). 
start() -> 
   Pid = spawn(fun() -> server("Hello") end), 
   Pid ! {hello}. 

server(Message) ->
   io:fwrite("~p",[Message]).

Получите … конец

Получает сообщение, которое было отправлено процессу. Он имеет следующий синтаксис —

Синтаксис

receive

Pattern1 [when Guard1] ->

Expressions1;

Pattern2 [when Guard2] ->

Expressions2;
...
End

Когда сообщение поступает в процесс, система пытается сопоставить его с шаблоном Pattern1 (с возможной защитой Guard1); если это успешно, это оценивает Выражения1. Если первый шаблон не совпадает, он пытается Pattern2, и так далее. Если ни один из шаблонов не совпадает, сообщение сохраняется для последующей обработки, и процесс ожидает следующего сообщения.

Пример всего процесса со всеми 3 командами показан в следующей программе.

пример

Live Demo

-module(helloworld). 
-export([loop/0,start/0]). 

loop() ->
   receive 
      {rectangle, Width, Ht} -> 
         io:fwrite("Area of rectangle is ~p~n" ,[Width * Ht]), 
         loop(); 
      {circle, R} ->
      io:fwrite("Area of circle is ~p~n" , [3.14159 * R * R]), 
      loop(); 
   Other ->
      io:fwrite("Unknown"), 
      loop() 
   end. 

start() ->
   Pid = spawn(fun() -> loop() end), 
   Pid ! {rectangle, 6, 10}.

Следующие вещи должны быть отмечены о вышеупомянутой программе —

  • Функция цикла имеет цикл приема конца. Поэтому, когда сообщение отправлено, оно будет обработано в конце цикла приема.

  • Появляется новый процесс, который переходит к функции цикла.

  • Сообщение отправляется порожденному процессу через Pid! команда сообщения.

Функция цикла имеет цикл приема конца. Поэтому, когда сообщение отправлено, оно будет обработано в конце цикла приема.

Появляется новый процесс, который переходит к функции цикла.

Сообщение отправляется порожденному процессу через Pid! команда сообщения.

Выход вышеуказанной программы —

Выход

Area of the Rectangle is 60

Максимальное количество процессов

При одновременном выполнении важно определить максимальное количество процессов, разрешенных в системе. После этого вы сможете понять, сколько процессов может одновременно выполняться в системе.

Давайте рассмотрим пример того, как мы можем определить, какое максимальное количество процессов может выполняться в системе.

Live Demo

-module(helloworld). 
-export([max/1,start/0]). 

max(N) -> 
   Max = erlang:system_info(process_limit), 
   io:format("Maximum allowed processes:~p~n" ,[Max]), 
   
   statistics(runtime), 
   statistics(wall_clock), 
   
   L = for(1, N, fun() -> spawn(fun() -> wait() end) end), 
   {_, Time1} = statistics(runtime), 
   {_, Time2} = statistics(wall_clock), lists:foreach(fun(Pid) -> Pid ! die end, L), 
   
   U1 = Time1 * 1000 / N, 
   U2 = Time2 * 1000 / N, 
   io:format("Process spawn time=~p (~p) microseconds~n" , [U1, U2]).
   wait() -> 
   
   receive 
      die -> void 
   end. 
 
for(N, N, F) -> [F()]; 
for(I, N, F) -> [F()|for(I+1, N, F)]. 

start()->
   max(1000), 
   max(100000).

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

Maximum allowed processes:262144

Process spawn time=47.0 (16.0) microseconds

Maximum allowed processes:262144

Process spawn time=12.81 (10.15) microseconds

Получить с тайм-аутом

Иногда оператор получения может ждать сообщения, которое никогда не приходит. Это может быть по ряду причин. Например, в нашей программе может быть логическая ошибка, или процесс, который собирался отправить нам сообщение, мог произойти сбой до отправки сообщения. Чтобы избежать этой проблемы, мы можем добавить тайм-аут в оператор получения. Это устанавливает максимальное время, в течение которого процесс будет ожидать получения сообщения.

Ниже приводится синтаксис полученного сообщения с указанным таймаутом.

Синтаксис

receive 
Pattern1 [when Guard1] -> 
Expressions1; 

Pattern2 [when Guard2] ->
Expressions2; 
... 
after Time -> 
Expressions 
end

Простейшим примером является создание функции спящего, как показано в следующей программе.

пример

-module(helloworld). 
-export([sleep/1,start/0]). 

sleep(T) ->
   receive 
   after T -> 
      true 
   end. 
   
start()->
   sleep(1000).

Выше код будет спать в течение 1000 мс перед фактическим выходом.

Выборочный прием

Каждый процесс в Erlang имеет связанный почтовый ящик. Когда вы отправляете сообщение процессу, оно помещается в почтовый ящик. Единственный раз, когда этот почтовый ящик проверяется, это когда ваша программа оценивает оператор получения.

Ниже приведен общий синтаксис оператора выборочного получения.

Синтаксис

receive 
Pattern1 [when Guard1] ->
Expressions1; 

Pattern2 [when Guard1] ->
Expressions1; 
... 
after 
Time ->
ExpressionTimeout 
end

Вот как работает вышеприведенный оператор получения —

  • Когда мы вводим оператор получения, мы запускаем таймер (но только если в выражении присутствует раздел после).

  • Возьмите первое сообщение в почтовом ящике и попробуйте сопоставить его с шаблоном Pattern1, Pattern2 и т. Д. Если совпадение успешно, сообщение удаляется из почтового ящика, и выражения, следующие за шаблоном, оцениваются.

  • Если ни один из шаблонов в операторе получения не соответствует первому сообщению в почтовом ящике, то первое сообщение удаляется из почтового ящика и помещается в «очередь сохранения». Затем пробуется второе сообщение в почтовом ящике. Эта процедура повторяется до тех пор, пока не будет найдено соответствующее сообщение или пока все сообщения в почтовом ящике не будут проверены.

  • Если ни одно из сообщений в почтовом ящике не совпадает, то процесс приостанавливается и будет перенесен на выполнение при следующем добавлении нового сообщения в почтовый ящик. Обратите внимание, что при поступлении нового сообщения сообщения в очереди сохранения не сопоставляются; только новое сообщение соответствует.

  • Как только сообщение сопоставлено, все сообщения, помещенные в очередь сохранения, повторно вводятся в почтовый ящик в порядке их поступления в процесс. Если таймер был установлен, он очищается.

  • Если таймер истекает, когда мы ждем сообщения, то оцениваем выражения ExpressionsTimeout и помещаем любые сохраненные сообщения обратно в почтовый ящик в том порядке, в котором они поступили в процессе.

Когда мы вводим оператор получения, мы запускаем таймер (но только если в выражении присутствует раздел после).

Возьмите первое сообщение в почтовом ящике и попробуйте сопоставить его с шаблоном Pattern1, Pattern2 и т. Д. Если совпадение успешно, сообщение удаляется из почтового ящика, и выражения, следующие за шаблоном, оцениваются.

Если ни один из шаблонов в операторе получения не соответствует первому сообщению в почтовом ящике, то первое сообщение удаляется из почтового ящика и помещается в «очередь сохранения». Затем пробуется второе сообщение в почтовом ящике. Эта процедура повторяется до тех пор, пока не будет найдено соответствующее сообщение или пока все сообщения в почтовом ящике не будут проверены.

Если ни одно из сообщений в почтовом ящике не совпадает, то процесс приостанавливается и будет перенесен на выполнение при следующем добавлении нового сообщения в почтовый ящик. Обратите внимание, что при поступлении нового сообщения сообщения в очереди сохранения не сопоставляются; только новое сообщение соответствует.

Как только сообщение сопоставлено, все сообщения, помещенные в очередь сохранения, повторно вводятся в почтовый ящик в порядке их поступления в процесс. Если таймер был установлен, он очищается.

Если таймер истекает, когда мы ждем сообщения, то оцениваем выражения ExpressionsTimeout и помещаем любые сохраненные сообщения обратно в почтовый ящик в том порядке, в котором они поступили в процессе.

Эрланг — Производительность

Говоря о производительности, следует отметить следующие моменты, касающиеся Erlang.

  • Funs очень быстрые — Funs получил собственный тип данных в R6B и был дополнительно оптимизирован в R7B.

  • Использование оператора ++ — этот оператор должен использоваться правильно. В следующем примере показан неправильный способ выполнения операции ++.

Funs очень быстрые — Funs получил собственный тип данных в R6B и был дополнительно оптимизирован в R7B.

Использование оператора ++ — этот оператор должен использоваться правильно. В следующем примере показан неправильный способ выполнения операции ++.

пример

-module(helloworld). 
-export([start/0]). 

start()->
   fun_reverse([H|T]) ->
   fun_reverse(T)++[H]; 
   fun_reverse([]) ->
   [].

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

  • Использование строк — обработка строк может быть медленной, если выполняется неправильно. В Erlang вам нужно немного подумать о том, как используются строки, и выбрать подходящее представление. Если вы используете регулярные выражения, используйте re-module в STDLIB вместо устаревшего модуля regexp .

  • BEAM — это стековая виртуальная машина с байт-кодом — BEAM — это виртуальная машина на основе регистров. Он имеет 1024 виртуальных регистра, которые используются для хранения временных значений и передачи аргументов при вызове функций. Переменные, которые должны пережить вызов функции, сохраняются в стек. BEAM — интерпретатор многопоточного кода. Каждая инструкция является словом, указывающим непосредственно на исполняемый C-код, что делает отправку команды очень быстрой.

Использование строк — обработка строк может быть медленной, если выполняется неправильно. В Erlang вам нужно немного подумать о том, как используются строки, и выбрать подходящее представление. Если вы используете регулярные выражения, используйте re-module в STDLIB вместо устаревшего модуля regexp .

BEAM — это стековая виртуальная машина с байт-кодом — BEAM — это виртуальная машина на основе регистров. Он имеет 1024 виртуальных регистра, которые используются для хранения временных значений и передачи аргументов при вызове функций. Переменные, которые должны пережить вызов функции, сохраняются в стек. BEAM — интерпретатор многопоточного кода. Каждая инструкция является словом, указывающим непосредственно на исполняемый C-код, что делает отправку команды очень быстрой.

Эрланг — Водители

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

Создание драйвера

Создание связанного драйвера — это самый эффективный способ взаимодействия кода на иностранном языке с Erlang, но он также и самый опасный. Любая фатальная ошибка в связанном драйвере приведет к сбою системы Erlang.

Ниже приведен пример реализации драйвера в Erlang:

пример

-module(helloworld). 
-export([start/0, stop/0]). 
-export([twice/1, sum/2]). 

start() ->
   start("example1_drv" ). 
start(SharedLib) ->
   case erl_ddll:load_driver("." , SharedLib) of 
   ok -> ok; 
      {error, already_loaded} -> ok; 
      _ -> exit({error, could_not_load_driver}) 
   end, 
   
   spawn(fun() -> init(SharedLib) end). 

init(SharedLib) -> 
   register(example1_lid, self()), 
   Port = open_port({spawn, SharedLib}, []), 
   loop(Port). 

stop() -> 
   example1_lid ! stop. 

twice(X) -> call_port({twice, X}). 
sum(X,Y) -> call_port({sum, X, Y}). call_port(Msg) -> 
   example1_lid ! {call, self(), Msg}, receive 
      {example1_lid, Result} -> 
      Result 
   end. 

LINKED-IN DRIVERS 223 
loop(Port) -> 
receive 
   {call, Caller, Msg} -> 
   Port ! {self(), {command, encode(Msg)}}, receive 
   {Port, {data, Data}} ->
   Caller ! {example1_lid, decode(Data)} 
   end, 

loop(Port); 
stop -> Port ! 
   {self(), close}, 
   receive 
      {Port, closed} -> 
      exit(normal) 
   end; 
   
      {'EXIT', Port, Reason} -> 
      io:format("~p ~n" , [Reason]), 
      exit(port_terminated) 
   end. 

encode({twice, X}) -> [1, X]; 
encode({sum, X, Y}) -> [2, X, Y]. decode([Int]) -> Int.

Обратите внимание, что работа с драйверами является чрезвычайно сложной, и следует проявлять осторожность при работе с драйверами.

Erlang — веб-программирование

В Erlang библиотека inets доступна для создания веб-серверов в Erlang. Давайте посмотрим на некоторые функции, доступные в Erlang для веб-программирования. Можно реализовать HTTP-сервер, также называемый httpd для обработки HTTP-запросов.

Сервер реализует множество функций, таких как —

  • Уровень защищенных сокетов (SSL)
  • Erlang Scripting Interface (ESI)
  • Общий интерфейс шлюза (CGI)
  • Аутентификация пользователя (с использованием Mnesia, Dets или простой текстовой базы данных)
  • Общий формат файла журнала (с поддержкой disk_log (3) или без нее)
  • URL Aliasing
  • Action Mappings
  • Списки каталогов

Первая задача — запустить веб-библиотеку с помощью команды.

inets:start()

Следующим шагом является реализация функции запуска библиотеки inets, чтобы можно было реализовать веб-сервер.

Ниже приведен пример создания процесса веб-сервера в Erlang.

Например

-module(helloworld). 
-export([start/0]). 

start() ->
   inets:start(), 
   Pid = inets:start(httpd, [{port, 8081}, {server_name,"httpd_test"}, 
   {server_root,"D://tmp"},{document_root,"D://tmp/htdocs"},
   {bind_address, "localhost"}]), io:fwrite("~p",[Pid]).

Следующие пункты должны быть отмечены о вышеупомянутой программе.

  • Номер порта должен быть уникальным и не использоваться никакими другими программами. Служба httpd будет запущена на этом порту нет.

  • Server_root и document_root являются обязательными параметрами.

Номер порта должен быть уникальным и не использоваться никакими другими программами. Служба httpd будет запущена на этом порту нет.

Server_root и document_root являются обязательными параметрами.

Выход

Ниже приведен вывод вышеуказанной программы.

{ok,<0.42.0>}

Чтобы реализовать веб-сервер Hello world в Erlang, выполните следующие шаги:

Шаг 1 — Реализуйте следующий код —

-module(helloworld). 
-export([start/0,service/3]). 

start() ->
   inets:start(httpd, [ 
      {modules, [ 
         mod_alias, 
         mod_auth, 
         mod_esi, 
         mod_actions, 
         mod_cgi, 
         mod_dir,
         mod_get, 
         mod_head, 
         mod_log, 
         mod_disk_log 
      ]}, 
      
      {port,8081}, 
      {server_name,"helloworld"}, 
      {server_root,"D://tmp"}, 
      {document_root,"D://tmp/htdocs"}, 
      {erl_script_alias, {"/erl", [helloworld]}}, 
      {error_log, "error.log"}, 
      {security_log, "security.log"}, 
      {transfer_log, "transfer.log"}, 
      
      {mime_types,[ 
         {"html","text/html"}, {"css","text/css"}, {"js","application/x-javascript"} ]} 
   ]). 
         
service(SessionID, _Env, _Input) -> mod_esi:deliver(SessionID, [ 
   "Content-Type: text/html\r\n\r\n", "<html><body>Hello, World!</body></html>" ]).

Шаг 2 — Запустите код следующим образом. Скомпилируйте вышеуказанный файл и затем выполните следующие команды в erl .

c(helloworld).

Вы получите следующий вывод.

{ok,helloworld}

Следующая команда —

inets:start().

Вы получите следующий вывод.

ok

Следующая команда —

helloworld:start().

Вы получите следующий вывод.

{ok,<0.50.0>}

Шаг 3 — Теперь вы можете получить доступ к URL — http: // localhost: 8081 / erl / hello_world: service .