Datové typy v programovacím jazyce Elixir

Published on: 2022-07-20

Integery

Jedná se o klasická celá čísla (…, -2, -1, 0, 1, 2, …). Elixir programátora neomezuje jak velké či malé celé číslo musí být. V Elixiru lze pracovat i s opravdu velkými čísly, pokud k tomu je dostatek paměti RAM. Opravdu obrovská čísla mají vliv na čas výpočtu, ale pro lidské vnímání je tohle zpomalení naprosto zanedbatelné.

iex(32)> 1234567891213138138138138138138138138 * 123214214214921472183210381203210302183 * 2137219321893821932819382198321939218312397219372179397213792173921 * 1232197321382109380213802183021830218302183021830218321083

400594646853992190082002975842596344158763794851066296804174448360912820881791327328524271478958550937298500527252420039610916215518991162308707268780961153676937620548947878554152771938882068481522

Pro lepší čitelnost čísel můžeme číslice oddělit podrtžítkem do skupin dle naší libosti, jak to umožňuje například i jazyk Python. Na čas kompilace to nemá žádný vliv. Elixir tyto podtržítka zcela ignoruje.

iex> 34_677_455_123
34677455123
iex> 34_4_1
3441

Pro práci s celými čísly jazyk Elixir poskytuje celou řadu užitečných funkcí nebo Guards. Některé funkce jako div nebo abs nalezneme jako součást jádra jazyka Elixir Kernel.

iex> div(10, 3)
3
iex> rem(10, 3)
1

Další užitečné funkce jako například digits a pow, nebo tzv. Guards jako is_even nalezneme v modulu Integer.

iex> Integer.digits(10)
[1, 0]
iex> Integer.pow(3, 2)
9

Datový typ Integer můžeme mezi sebou sčítat, odečítat, násobit či dělit. V případě dělení je výsledek automaticky převeden na datový typ Float. elixir iex> 3 + 4 7 iex> 2 - 4 -2 iex> 3 * 4 12 iex> 12 / 3 4.0

Integers lze také pomocí předpony v zápisu zapsat v různých číselných soustavách:

iex> 0b0111
7
iex> 0o345
229
iex> 0xFF
255

Floaty

Jedná se o čísla s plovoucí čárkou, zjednodušeně desetinná čísla. Jedná se o čísla, která mají alespoň jedno desetinné místo - desetinná čísla. I když se tyto čísla někdy nazývají s také jako čísla s plouvoucí čárkou, v jazyce Elixir je zapisujeme pomocí tečky. elixir iex> float_number = 8.34 8.34 iex> i float_number Term 8.34 Data type Float Reference modules Float Implemented protocols IEx.Info, Inspect, List.Chars, String.Chars iex> IEx.Info.info(8.34) [{"Data type", "Float"}, {"Reference modules", "Float"}]

Jazyk Elixir používá formát 64-bit s dvojitou přesností. They use the 64-bit double precision floating-point format.

Práce s čísly typu Float je velmi podobná jako s Integers.

Například podtržítka fungují stejně.

iex> 23_34.43_222
2334.43222

Užitečné funkce pro práci s Floats nalezneme opět v Kernelu a v modulu Float

Elixir má podporu vědeckého zápisu čísel typu float pomocí exponentu e. elixir iex> 12345.999e-2 123.45999

Pozor si musíme dát na jemnou nepřesnost při výpočtech desetinné části. Z tohoto důvodu se nedoporučuje tento typ používat na výpočty financí. S tímto problémem se ovšem potýká více programovacích jazyků. Pro přesné výpočty se používají speciální datové type jako například v C# čísla s pevnou desetinnou tečkou (fixed-point number).

iex> 3.34 - 3.35
-0.010000000000000231

Atomy

Atom je konstanta, jehož jméno je zároveň jeho hodnotou. Jedná se o stejnou filosofii s jakou Symboly fungují v jazyce Ruby.

Upřímně, dlouho mi trvalo než jsem atomy dostal trochu více pod kůži. Moc jsem nechápal jejich přidanou hodnotu a proč nestačí mít pouze datový typ string. Všude přítomné vysvětlení, že se jedná o konstantu, jejíž jméno je zároveň její hodnotou, mi úplně nepomohlo. Naštěstí jsem nalezl docela užítečný článek[1], který se o této problematice rozepisuje trochu více. Je dobré si uvědomit, že atomy jsou konstanty s unikátní hodnotou. Často se tak setkáte s atomy :ok nebo :error, které vyjadřují stav nějaké operace. Tento případ přímo vybízí k použití něčeho jako jsou atomy.

iex> :pes == :kocka
false
iex> :pes == :pes
true

Díky své unikátnosti se atomy hodí také jako klíče to struktur typu klíč - hodnota. Atomy se v jazyce Elixir ukládájí do jakési tabulky atomů, kde jsou uloženy po celou dobu. Jakmile jednou vytvoříte atom, tak už jej nevymažete. Jejich vnitřní hodnotu nelze změnit.[4] Není tedy dobrý nápad vytvářet velký počet atomů. Navíc, maximální počet atomů je v Erlang virtual machine omezen na 1,048,576.[1] Když uložíte do více proměnných stejný atom, tak tento atom existuje ve skutečnosti pouze jednou a je všemi proměnnými sdílen. Atomy jsou unikátní napříč celým runtime prostředím, což je velmi užitečná vlastnost pro komunikaci napříč procesy. Atomy jsou vlastně takové globální proměnné. Naproti tomu většina dat v Elixiru včetně stringů zůstavají alokována v daném procesu. Další výhodou oproti stringům je fakt, že práce s atomy je daleko efektivnější. Atomy jsou vnitřně ukládány jako integers, takže například porovnávání atomů je daleko rychlejší než mezi stringy.[1][4] Z výše uvedených důvodů se nedoporučuje zacházet s atomy s jako dynamickými daty, napříkladukládat vstupy uživatelů v datovém typu atom. Posledním faktem je, že Erlang VM má postavený celý koncept paralelizace na atomech.[1]

Zápis atomu začíná dvojtečkou :, za kterou musí následovat text.

iex> :foo
:foo
iex> i(:foo)
Term
  :foo
Data type
  Atom
Reference modules
  Atom
Implemented protocols
  IEx.Info, Inspect, List.Chars, String.Chars

Všechny atomy musí začínat po dvojtečce písmenem, v opačném případě dostaneme SyntaxError.

iex> :4ee
** (SyntaxError) iex:25:1: unexpected token: ":" (column 1, code point U+003A)
iex> :@ab
** (SyntaxError) iex:55:3: syntax error before: ab
iex> :e43
:e43
iex> :foo@bar
:foo@bar

Více slovní atomy oddělujeme podtržítkem.

iex> :atom_z_vice_slov
:atom_z_vice_slov

Pokud potřebujeme použít zakázané znaky na začátku atomu (čísla, @, !, ? …) nebo použít mezer mezi slovy, musíme celý název atomu obalit do uvozovek.

iex> :"atom z vice slov"
:"atom z vice slov"
iex> :"12"
:"12"
iex> :"@ab"
:"@ab"

Ke kontrole, zda je daný objekt atom či nikoliv můžeme použít vestavěnou funkci is_atom.

iex> is_atom(:foo)
true
iex> is_atom :foo
true
iex> is_atom "foo"
false
iex> is_atom 444
false

Existuje i několik výjimek u kterých se nemusí psát počáteční dvojtečka. Jedná se o true, false a nil. V těchto případech vůbec nezáleží jestli před ně dvojtečku napíšeme či nikoliv a pořád se jedná o jeden stejný objekt.

iex> is_atom(true)
true
iex> is_atom(:true)
true
iex> true == :true
true
iex> is_atom(nil)
true
ies> nil == :nil
true

Další objekty u kterých bychom nejspíš nečekali, že budou atomy jsou aliasy a názvy modulů včetně modulů, které nejsou deklarované. U těchto atomů se totiž dvojtečky vůbec nepíšou. Neplatí pro ně jako v předchozím příkladu, že v případě objektu s dvojtečkou a bez se jedná o totéž.

iex> is_atom(Ahoj)
true
iex> is_atom(:Ahoj)
true
iex(8)> Ahoj == :Ahoj
false
iex> is_atom(MojeAplikace.MujModul)
true

Atomy se používají také v názvu Erlangových modulů při odkazování na konkrétní funkci.[3] Erlangové moduly na rozdíl od elixírových začínají malým písmenem, nejedná se u nich tedy o Aliasy. Volání erlanogových modulů je v Elixíru vyřešeno pomocí Atomů. Více to bude možná jasnější z kapitoly Aliasy.

iex> :crypto.strong_rand_bytes 3
<<23, 104, 108>>

Aliasy

Aliasy jsou atomy, ale začínají místo dvojtečky : velkým písmenem.

iex> is_atom(Ahoj)
true

Aliasy se v Elixíru nastavují následujícím způsobem.

iex> alias :nejaky_dlouhy_atom, as: MujAlias
:nejaky_dlouhy_atom
iex> MujAlias
:nejaky_dlouhy_atom
iex> Atom.to_string(MujAlias)
:nejaky_dlouhy_atom

Alias lze použít i bez toho, aniž bychom jej dopředu nastavili. Výchozí hodnota takového Aliasu je nastavena jako atom :"Elixir.DalsiAlias”. Voláme-li námi definovaný modul hledá se pod cestou Elixir.NasModul. Vytvoříme-li soubor zviratka.ex a nadefinujeme si s v něm moduly Pes a Kočka, po kompilaci budeme mít k dispozici Elixir.Pes.beam a Elixir.Kočka.beam.

iex> DalsiAlias
DalsiAlias
iex> Atom.to_string(DalsiAlias)
"Elixir.DalsiAlias"
iex> DalsiAlias == "Elixir.DalsiAlias"
false
iex> DalsiAlias == :"Elixir.DalsiAlias"
true

Definice aliasu lze zapsat takě bez nově definovaného jména (odkazu).

alias MyApp.Account.User
# je totéž jako bychom napsali
alias MyApp.Account.User, as: User

Aliasy se používají především v případech, kde potřebujeme vytvořit odkaz například na modul pod kratším či vhodnějším jménem. V příkladu níže si pomocí aliasu můžeme nastavit zkrácené jméno (odkaz) I pro modul Integer, nově tak můžeme modul Integer volat pouze pomocí odkazu I.

alias Integer, as: I
I.pow(2, 3)

Dobrým zvykem je definovat aliasy na začátku modulu.

Booleans

Programovací jazyk Elixir podporuje dvě boolean hodnoty a to true a false. Velmi zajímavé je, že ve skutečnosti jsou tyto booleanovské hodnoty pouze odkazy k atomům :true a :false. Hodnoty true a false jsou tedy čistě jen pseudonymy pro atomy.

Všechny boolean hodnoty jsou atomy a ne všechny atomy jsou booleany.[1]

iex(27)> true == :true
true
iex(28)> true === :true
true

Strings

Binaries

Bitstrings

Charlists

Ranges

Collection types

Tuples

Lists

Keyword lists

Maps

Sets

Binaries/Bitstrings

Structs

Sigils

regex

Speciální datové typy

Port

Reference

pid

Zdroje

[1] inquisitivedeveloper [2] elixir-lang.org [3] elixirschool.com [4] exercism [5] tutorialspoint