Die Datentypen
| Typ | Beispiel |
|---|---|
| Integer | 42, 1_000_000, 0xFF |
| Float | 3.14, 1.0e3 |
| Boolean | true, false (eigentlich Atome) |
| Atom | :ok, :fehler, :"mit leer"; nil ist :nil |
| String | "Text" (UTF-8-Binärdaten) |
| Liste | [1, 2, 3] (verkettet) |
| Tupel | {:ok, 42} (feste Größe) |
| Map | %{name: "Mia", alter: 17} |
| Keyword-Liste | [a: 1, b: 2] (Liste von {atom, wert}) |
| Range | 1..10 |
| Funktion | fn x -> x * 2 end |
IO.inspect({1, "zwei", :drei, 4.0, [5], {6}})
IO.inspect(is_integer(5))
IO.inspect(is_atom(:ok))
IO.inspect(is_binary("text"))
IO.inspect(is_list([1]))
IO.inspect(is_map(%{}))
IO.inspect(is_function(fn -> 1 end))
IO.inspect(round(3.5))
IO.inspect(trunc(3.9))
IO.inspect(max(3, 9))
IO.inspect(abs(-5))
IO.inspect(:erlang.float_to_binary(3.14159, decimals: 2))
IO.inspect(1 == 1.0)
IO.inspect(1 === 1.0)
IO.inspect("abc" < "abd")
IO.inspect(:a < :b)
IO.inspect(Integer.parse("42abc"))
IO.inspect(String.to_integer("7") + 1)
IO.inspect(1_000_000 * 1_000_000 * 1_000_000){1, "zwei", :drei, 4.0, [5], {6}}
true
true
true
true
true
true
4
3
9
5
"3.14"
true
false
true
true
{42, "abc"}
8
1000000000000000000Strings
s = "Hallo Welt"
IO.inspect(String.length(s))
IO.inspect(String.upcase(s))
IO.inspect(String.downcase(s))
IO.inspect(String.reverse(s))
IO.inspect(String.split(s, " "))
IO.inspect(String.replace(s, "Welt", "Elixir"))
IO.inspect(String.contains?(s, "Welt"))
IO.inspect(String.starts_with?(s, "Hal"))
IO.inspect(String.slice(s, 0, 5))
IO.inspect(String.trim(" x "))
IO.inspect(String.capitalize("elixir"))
IO.inspect(String.pad_leading("7", 3, "0"))
IO.inspect(s <> "!")
IO.inspect("a" <> "b" <> "c")
IO.inspect(String.duplicate("ab", 3))
IO.inspect(String.graphemes("Häx"))
IO.inspect(String.codepoints("Häx"))
IO.inspect(byte_size("Häx"))
IO.inspect(String.at("Elixir", 2))
IO.inspect(Enum.join(["a", "b"], "-"))
IO.inspect(to_string(42) <> "!")
IO.inspect("Zeile 1\nZeile 2" |> String.split("\n"))
IO.puts("Mehrzeilig:
Text bleibt erhalten")
IO.inspect(~s(Sigil mit "Anführungszeichen"))
IO.inspect(~w(rot grün blau))
IO.inspect(~w(a b c)a)10 "HALLO WELT" "hallo welt" "tleW ollaH" ["Hallo", "Welt"] "Hallo Elixir" true true "Hallo" "x" "Elixir" "007" "Hallo Welt!" "abc" "ababab" ["H", "ä", "x"] ["H", "ä", "x"] 4 "i" "a-b" "42!" ["Zeile 1", "Zeile 2"] Mehrzeilig: Text bleibt erhalten "Sigil mit \"Anführungszeichen\"" ["rot", "grün", "blau"] [:a, :b, :c]
Pattern Matching: das `=` ist kein Zuweisen
In Elixir ist = der Match-Operator: Die linke Seite wird so an die rechte angepasst, dass beide gleich sind. Dabei werden Variablen gebunden.
{a, b} = {1, 2}
IO.inspect({a, b})
[kopf | rest] = [10, 20, 30]
IO.inspect({kopf, rest})
[x, y | _] = [1, 2, 3, 4]
IO.inspect({x, y})
{:ok, wert} = {:ok, 42}
IO.inspect(wert)
%{name: n} = %{name: "Mia", alter: 17}
IO.inspect(n)
[a1, _, a3] = [:a, :b, :c]
IO.inspect({a1, a3})
^a = 1 # Pin-Operator: bestehenden Wert prüfen, nicht neu binden
IO.inspect(a)
ergebnis =
try do
{:ok, _} = {:fehler, "kaputt"}
rescue
e in MatchError -> "kein Match: #{inspect(e.term)}"
end
IO.puts(ergebnis)
{status, _} = {:ok, 1}
IO.inspect(status)
"Hallo " <> rest = "Hallo Welt"
IO.inspect(rest)
<<erstes::binary-size(2), _::binary>> = "Elixir"
IO.inspect(erstes){1, 2}
{10, [20, 30]}
{1, 2}
42
"Mia"
{:a, :c}
1
kein Match: {:fehler, "kaputt"}
:ok
"Welt"
"El"Typisches Idiom: Funktionen liefern {:ok, wert} oder {:error, grund} und der Aufrufer matcht darauf (siehe Fehlerbehandlung).
Listen, Tupel, Maps, Keyword-Listen
liste = [3, 1, 2]
IO.inspect(liste ++ [4])
IO.inspect(liste -- [1])
IO.inspect(hd(liste))
IO.inspect(tl(liste))
IO.inspect(length(liste))
IO.inspect(Enum.at(liste, 1))
IO.inspect(2 in liste)
IO.inspect([1, 2] ++ [3] |> Enum.reverse())
IO.inspect(List.first(liste))
IO.inspect(List.last(liste))
IO.inspect(Enum.sort(liste))
IO.inspect(List.delete(liste, 1))
IO.inspect(List.insert_at(liste, 1, :x))
t = {:ok, "Daten", 3}
IO.inspect(elem(t, 1))
IO.inspect(tuple_size(t))
IO.inspect(put_elem(t, 1, "neu"))
m = %{"text-key" => 1, name: "Mia", alter: 17}
IO.inspect(m.name)
IO.inspect(m[:alter])
IO.inspect(m["text-key"])
IO.inspect(Map.get(m, :fehlt, "Standard"))
IO.inspect(Map.put(m, :stadt, "Berlin") |> Map.keys() |> Enum.map(&inspect/1) |> Enum.sort())
IO.inspect(%{m | alter: 18})
IO.inspect(Map.delete(m, :alter) |> map_size())
IO.inspect(Map.has_key?(m, :name))
IO.inspect(Map.merge(%{a: 1}, %{b: 2, a: 3}))
IO.inspect(Map.new([{:x, 1}, {:y, 2}]))
IO.inspect(Map.to_list(%{b: 2, a: 1}))
IO.inspect(Map.values(%{a: 1, b: 2}))
IO.inspect(get_in(%{a: %{b: %{c: 42}}}, [:a, :b, :c]))
IO.inspect(update_in(%{zaehler: 1}, [:zaehler], &(&1 + 1)))
kw = [farbe: "rot", groesse: 3]
IO.inspect(kw[:farbe])
IO.inspect(Keyword.get(kw, :groesse))
IO.inspect(kw == [{:farbe, "rot"}, {:groesse, 3}])[3, 1, 2, 4]
[3, 2]
3
[1, 2]
3
1
true
[3, 2, 1]
3
2
[1, 2, 3]
[3, 2]
[3, :x, 1, 2]
"Daten"
3
{:ok, "neu", 3}
"Mia"
17
1
"Standard"
["\"text-key\"", ":alter", ":name", ":stadt"]
%{:alter => 18, :name => "Mia", "text-key" => 1}
2
true
%{a: 3, b: 2}
%{x: 1, y: 2}
[a: 1, b: 2]
[1, 2]
42
%{zaehler: 2}
"rot"
3
trueMerke
- Typen: Integer, Float, Atom, String, Liste, Tupel, Map, Keyword-Liste, Range, Funktion
- Strings sind UTF-8,
<>verkettet,String.*für Funktionen =ist der Match-Operator; mit^pinnst du Werte- Listen
[kopf | rest], Tupel{:ok, wert}, Maps%{key: value} - Datenstrukturen sind unveränderlich:
Map.put,%{m | key: v}liefern neue Werte
Aufgabe
Zerlege {:ok, [1, 2, 3]} per Pattern Matching in Status, ersten Wert und Rest.