Erlang Language Zelfstudie
Aan de slag met Erlang Language
Zoeken…
Opmerkingen
"Erlang is een programmeertaal die oorspronkelijk is ontwikkeld door het Ericsson Computer Science Laboratory. OTP (Open Telecom Platform) is een verzameling middleware en bibliotheken in Erlang. Erlang / OTP is in een aantal Ericsson-producten getest in de strijd om robuuste fouttolerantie te bouwen gedistribueerde applicaties, bijvoorbeeld AXD301 (ATM-switch). Erlang / OTP wordt momenteel onderhouden door de Erlang / OTP-eenheid bij Ericsson "( erlang.org )
Begin hier
Zie Installatie- onderwerp voor installatie-instructies.
Links
- Officiële Erlang-site: https://www.erlang.org
- Populaire pakketbeheerder voor zowel Erlang als Elixir: http://hex.pm
- Erlang-patronen: http://www.erlangpatterns.org/
versies
Hallo Wereld
Er zijn twee dingen die u moet weten bij het schrijven van een "hallo wereld" -toepassing in Erlang:
- De broncode is geschreven in de programmeertaal Erlang met behulp van de gewenste teksteditor
- De toepassing wordt vervolgens uitgevoerd in de virtuele machine van Erlang . In dit voorbeeld zullen we communiceren met de erlang VM via de erlangshell.
Eerst de applicatie broncode:
Maak een nieuw bestand hello.erl
met het volgende:
-module(hello).
-export([hello_world/0]).
hello_world() ->
io:format("Hello, World!~n", []).
Laten we snel kijken wat dit betekent:
-
-module(hello).
Alle erlang-functies bestaan binnen een module . Modules worden vervolgens gebruikt om applicaties te bouwen, een verzameling modules. Deze eerste regel is om deze module te identificeren, namelijk hallo . Modules kunnen worden vergeleken met Java's pakketten -
-export([hello_world/0]).
Vertelt de compiler die functioneert om "openbaar" te maken (in vergelijking met OO-talen), en de arity van de relevante functie. De arity is het aantal argumenten dat de functie aanneemt. Omdat in erlang een functie met 1 argument wordt gezien als een andere functie dan een met 2 argumenten, hoewel de naam exact hetzelfde kan zijn. Dat wil zeggen,hello_world/0
is een compleet andere functie dan bijvoorbeeldhello_world/1
. -
hello_world()
Dit is de naam van de functie. De->
geeft de overgang aan naar de implementatie (hoofdtekst) van de functie. Dit kan worden gelezen als "hello_world () is gedefinieerd als ...". Merk op dathello_world()
(geen argumenten) wordt geïdentificeerd doorhello_world/0
in de VM enhello_world(Some_Arg)
alshello_world/1
. -
io:format("Hello, World!~n", [])
Vanuit moduleio
wordt de functieformat/2
functie genoemd, wat de functie is voor standaarduitvoer.~n
is een opmaakaanduiding die betekent dat een nieuwe regel moet worden afgedrukt. De[]
is een lijst met af te drukken variabelen aangegeven door formaatspecificaties in de uitvoertekenreeks, wat in dit geval niets is. - Alle erlang-uitspraken moeten eindigen op een
.
(punt).
In Erlang wordt het resultaat van de laatste instructie in een functie geretourneerd.
Laten we nu onze applicatie uitvoeren:
Start de erlang-shell vanuit dezelfde map als het bestand hello.erl
:
$ erl
U zou een prompt moeten krijgen die er ongeveer zo uitziet (uw versie kan anders zijn):
Eshell V8.0 (abort with ^G)
1>
Voer nu de volgende opdrachten in:
1> c(hello).
{ok,hello}
2> hello:hello_world().
Hello, World!
ok
Laten we elke regel één voor één doorlopen:
-
c(hello)
- dit commando roept de functiec
op een atoomhello
. Dit vertelt Erlang effectief om het bestandhello.erl
te vinden, het in een module te compileren (een bestand met de naamhello.beam
wordt in de map gegenereerd) en in de omgeving te laden. -
{ok, hello}
- dit is het resultaat van het aanroepen van de functiec
hierboven. Het is een tupel met een atoomok
en een atoomhello
. Erlang-functies retourneren meestal{ok, Something}
of{error, Reason}
. -
hello:hello_world()
- dit roept een functiehello_world()
vanuit de modulehello
. -
Hello, World!
- dit is wat onze functie afdrukt. -
ok
- dit is wat onze functie terugkeerde. Aangezien Erlang een functionele programmeertaal is, retourneert elke functie iets . In ons geval, hoewel we niets hebben terug te keren inhello_world()
, het laatste gesprek in die functie was omio:format(...)
en die functie terugok
, dat op zijn beurt wat onze functie teruggekeerd.
modules
Een erlang-module is een bestand met een aantal gegroepeerde functies. Dit bestand heeft .erl
extensie .erl
.
Een module "Hallo wereld" met de naam hello.erl
wordt hieronder weergegeven
-module(hello).
-export([hello_world/0]).
hello_world() ->
io:format("Hello, World!~n", []).
In het bestand moet de modulenaam worden opgegeven. Zoals eerder getoond in regel 1. De modulenaam en de bestandsnaam vóór de extensie .erl
moeten hetzelfde zijn.
Functie
Functie is een set instructies, die zijn gegroepeerd. Deze gegroepeerde instructies voeren samen een bepaalde taak uit. In erlang zullen alle functies een waarde retourneren wanneer ze worden aangeroepen.
Hieronder ziet u een voorbeeld van een functie die twee getallen toevoegt
add(X, Y)-> X + Y.
Deze functie voert een optelbewerking uit met X- en Y-waarden en retourneert het resultaat. Functie kan worden gebruikt zoals hieronder
add(2,5).
Functieverklaringen kunnen uit meerdere clausules bestaan, gescheiden door een puntkomma. De argumenten in elk van deze clausules worden geëvalueerd door patroonvergelijking. De volgende functie retourneert 'tuple' als het argument een tuple in het formulier is: {test, X} waarbij X elke waarde kan hebben. Het zal 'lijst' retourneren, als het argument een lijst met lengte 2 is in de vorm ["test", X], en het zal '{error, "Reason"}' in een ander geval retourneren:
function({test, X}) -> tuple;
function(["test", X]) -> list;
function(_) -> {error, "Reason"}.
Als het argument geen tupel is, wordt de tweede clausule geëvalueerd. Als het argument geen lijst is, wordt de derde clausule geëvalueerd.
Functieverklaringen kunnen bestaan uit zogenaamde 'Guards' of 'Guard Sequences'. Deze bewakers zijn uitdrukkingen die de evaluatie van een functie beperken. Een functie met bewakers wordt alleen uitgevoerd wanneer alle Guard Expressions een echte waarde opleveren. Meerdere bewakers kunnen worden gescheiden door een puntkomma.
function_name(Argument) when Guard1; Guard2; ... GuardN -> (...).
De functie 'functienaam' wordt alleen geëvalueerd als de Guard Sequence waar is. De volgende functie retourneert alleen true als het argument X
zich in het juiste bereik bevindt (0..15):
in_range(X) when X>=0; X<16 -> true;
in_range(_) -> false.
Lijstbegrip
Lijstbegrippen zijn een syntactische constructie om een lijst te maken op basis van bestaande lijsten.
In erlang heeft een lijstbegrip de vorm [Expr || Qualifier1, ..., QualifierN]
.
Waar kwalificaties ofwel generatoren zijn Pattern <- ListExpr
of filteren als integer(X)
met een waarde true
of false
.
Het volgende voorbeeld toont een lijstbegrip met één generator en twee filters.
[X || X <- [1,2,a,3,4,b,5,6], integer(X), X > 3].
Het resultaat is een lijst met alleen gehele getallen groter dan 3.
[4,5,6]
De Erlang-shell starten en stoppen
De Erlang-shell starten
Op een UNIX-systeem start u de Erlang-shell vanaf een opdrachtprompt met de opdracht erl
Voorbeeld:
$ erl
Erlang/OTP 18 [erts-7.0] [source] [64-bit] [smp:8:8] [async-threads:10] [hipe] [kernel-poll:false]
Eshell V7.0 (abort with ^G)
1>
De tekst die wordt weergegeven wanneer u de shell start, vertelt u informatie over welke versie van Erlang u gebruikt, evenals andere nuttige informatie over het erlang-systeem.
Om de shell op Windows te starten, klikt u op het Erlang-pictogram in het Windows-startmenu.
De Erlang-shell stoppen
Voor een gecontroleerde uitgang van de erlang-shell typt u:
Erlang/OTP 18 [erts-7.0] [source] [64-bit] [smp:8:8] [async-threads:10] [hipe] [kernel-poll:false]
Eshell V7.0 (abort with ^G)
1> q().
U kunt de Erlang-shell ook verlaten door op Ctrl + C te drukken op UNIX-systemen of Ctrl + Break op Windows, wat u naar de volgende prompt brengt:
Erlang/OTP 18 [erts-7.0] [source] [64-bit] [smp:8:8] [async-threads:10] [hipe] [kernel-poll:false]
Eshell V7.0 (abort with ^G)
1>
BREAK: (a)bort (c)ontinue (p)roc info (i)nfo (l)oaded
(v)ersion (k)ill (D)b-tables (d)istribution
Als u vervolgens op a (voor afbreken) drukt, verlaat u de shell direct.
Andere manieren om de erlang-shell te verlaten zijn: init:stop()
die hetzelfde doet als q()
of erlang:halt()
.
Patroon matching
Een van de meest voorkomende bewerkingen in erlang is patroonovereenkomst. Het wordt gebruikt bij het toekennen van een waarde aan een variabele, in functieverklaringen en in control-flowstructuren zoals case
en receive
instructies. Een patroonafstemmingsbewerking heeft minimaal 2 delen nodig: een patroon en een term waartegen het patroon overeenkomt.
Een variabele toewijzing in erlang ziet er zo uit:
X = 2.
In de meeste programmeertaal is de semantiek van deze bewerking eenvoudig: bind een waarde ( 2
) aan een naam naar keuze (de variabele - in dit geval X
). Erlang heeft een iets andere aanpak: vergelijk het patroon aan de linkerkant ( X
) met de term aan de rechterkant ( 2
). In dit geval is het effect hetzelfde: de variabele X
is nu gebonden aan de waarde 2
. Met patroonmatching kunt u echter meer gestructureerde opdrachten uitvoeren.
{Type, Meta, Doc} = {document, {author, "Alice"}, {text, "Lorem Ipsum"}}.
Deze matching-operatie wordt uitgevoerd door de structuur van de rechterterm te analyseren en alle variabelen aan de linkerkant op de juiste waarden van de term toe te passen, zodat de linkerkant gelijk is aan de rechterkant. In dit voorbeeld is Type
gebonden aan de term: document
, Meta
aan {author, "Alice"}
en Doc
aan {text, "Lorem Ipsum"}
. In dit specifieke voorbeeld worden de variabelen: Type
, Meta
en Doc
verondersteld ongebonden te zijn , zodat elke variabele kan worden gebruikt.
Patroonmatchings kunnen ook worden gebouwd met behulp van gebonden variabelen.
Identifier = error.
De variabele Identifier
is nu gebonden aan de error
. De volgende patroonvergelijkingsbewerking werkt, omdat de structuur overeenkomt en de gebonden variabele Identifier
dezelfde waarde heeft als het juiste rechterdeel van de term.
{Identifier, Reason} = {error, "Database connection timed out."}.
Een patroonafstemmingsbewerking mislukt, wanneer er een mismatch is tussen de rechterterm en het linkerpatroon. De volgende overeenkomst zal mislukken, omdat Identifier
gebonden is aan de error
, die geen juiste uitdrukking heeft aan de rechterkant.
{Identifier, Reason} = {fail, "Database connection timed out."}.
> ** exception error: no match of right hand side value {fail,"Database ..."}