generated at
Elixir入門
拡張子
.ex - アプリケーションコードはこっち. 最終的にバイトコードにコンパイルして実行します
.exs - テストコードやスクリプトはこっち
実行方法
$ elixir file.exs
sh
$ iex iex(1)> c file.exs

ビルドツール

条件分岐

ピン演算子
変数の現在の値をパターンマッチのパターンとして使います
elixir
a = 100 ^a = 100 # => 👌OK ^a = 200 # => 🙅NG [1, ^a, 3] = [1, 100, 3] # => 👌OK [1, ^a, 3] = [1, 200, 3] # => 🙅NG key = "name" %{ ^key => name } = %{ "name" => "hoge" } # => 👌OK (%{"name" => "hoge"})

データ構造
タプル
elixir
{ 1, 2 } { :ok, "hello" }

リスト
elixir
# 空リスト [] # パターンマッチ [a, b, c] = [10, 20, 30] a # => 10 b # => 20 c # => 30 [head | tail] = [1,2,3,4,5] head # => 1 tail # => [2,3,4,5] # 連結 [1,2] ++ [3,4,5] # => [1,2,3,4,5] # 要素の確認 1 in [1, 2, 3] # => true "hello" in [10, 20] # => false # Listモジュール List.flatten([[1,2], [[3]], 4]) # => [1, 2, 3, 4] List.foldl([10, 20, 30], 0, fn x, sum -> sum + x end) # => 60 List.replace_at([1,2,3], 1, 100) # => [1, 100, 3] List.keyfind([{:a, "hoge"}, {:b, "fuga"}], :a, 0) # => {:a, "hoge"} List.keyfind([{:foo, 1}, {:bar, 2}, {:baz, 3}], 2, 1) # => {:bar, 2} List.keydelete([{:foo, 1}, {:bar, 2}, {:baz, 3}], 2, 1) # -=> [foo: 1, baz: 3] List.keyreplace([{:foo, 1}, {:bar, 2}, {:baz, 3}], 2, 1, {:hoge, 20}) # => [foo: 1, hoge: 20, baz: 3]

キーワードリスト
elixir
# 記法 [ name: "hoge", age: 20 ] # => `[ {:name, "hoge"}, {:age, 20} ]`と同義 [name: "hoge", height: 160][:name] # => "hoge" # 最後の引数がキーワードリストの場合、ブラケットを省略できる do_something arg, opt1: 1, opt2: "hello" # `do_something arg, [opt1: 1, opt2: "hello"]`と同義 # Keywordモジュール Keyword.get([name: "hoge", age: 15, name: "piyo"], :name) # => "hoge" Keyword.get([a: 1, b: 2], :c, 3) # => 3 Keyword.get_values([name: "hoge", age: 80, name: "fuga"], :name) # => ["hoge", "fuga"] Keyword.merge([name: "hoge", age: 3], [name: "piyo", height: 180]) # => [age: 3, name: "piyo", height: 180]

マップ
elixir
map = %{ name: "piyo", age: 10 } map[:name] # => "piyo" map = %{ map | name: "hoge" } # => %{age: 10, name: "hoge"} # パターンマッチ %{ name: a_name } = %{ name: "hoge", age: 30 } # => %{age: 30, name: "hoge"} a_name # => "hoge" %{ name: _, age: _ } = %{ name: "hoge", age: 24 } # => %{age: 24, name: "hoge"} %{ name: a_name } = %{ a: 1 } # => 🙅NG %{ name: "hoge" } = %{ name: "hoge", age: 30 } # => OK %{ name: "piyo" } = %{ name: "hoge", age: 30 } # => 🙅NG # Mapモジュール Map.keys %{ name: "hoge", age: 15 } # => [:age, :name] Map.values %{ first_name: "hoge", last_name: "fuga" } # => ["hoge", "piyo"] Map.drop %{ first_name: "hoge", last_name: "piyo", age: 10 }, [:first_name, :last_name] # => %{age: 10} Map.put %{ name: "hoge" }, :likes, "Elixir" # => %{likes: "Elixir", name: "hoge"} Map.has_key? %{ first_name: "hoge" }, :last_name # => false Map.pop %{ name: "piyo", likes: "Deno" }, :likes # => {"Deno", %{name: "piyo"}} Map.equal? %{ a: 1, b: 2 }, %{ a: 1, b: 2 } # => true Map.put_new(%{ name: "hoge" }, :height, 180) # => %{height: 180, name: "hoge"}

セット
MapSet を使う
elixir
MapSet.new # => #MapSet<[]> set = Enum.into(1..10, MapSet.new) # => #MapSet<[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]> MapSet.member? set, 4 # => true

構造体
モジュール名が構造体の名前として扱われます
モジュール内でdefstructマクロを使用して構造を定義します
elixir
defmodule User do defstruct name: "", age: 15 def to_string(%User{name: name, age: age}) do "name: #{name}, age: #{age}" end end

elixir
%User{} # => %User{age: 15, name: ""} %User{ name: "hoge" } # => %User{age: 15, name: "hoge"} %User{ name: "hoge", no_such_key: true } # => 🙅NG (KeyError) # フィールドへのアクセス user = %User{} user.age # => 15 # パターンマッチ %User{ name: user_name } = user user_name # => "" # 更新 user = %User{ user | name: "piyo" } # => %User{age: 15, name: "piyo"} User.to_string(user) # => "name: , age: 15"

コレクションの処理
elixir
Enum.map([1,2,3], &(&1 * 2)) # => [2, 4, 6]

ストリーム
elixir
# Enumモジュールの関数にストリームを渡すと結果を得られる Stream.map([1,2,3,4,5], &(&1*&1)) |> Enum.to_list # => [1, 4, 9, 16, 25] Stream.map([1,2,3,4,5], &(&1*&1)) |> Stream.map(&(&1*2)) |> Enum.to_list # => [2, 8, 18, 32, 50] # Stream.cycle => 列挙可能なデータから無限ストリームを生成する。最後の要素まで到達したら、最初の要素に戻る Stream.cycle([1,2,3]) |> Enum.take(5) # => [1, 2, 3, 1, 2] # Stream.repeatedly Stream.repeatedly(fn -> 1 end) |> Enum.take(3) # => [1, 1, 1] # Stream.iterate Stream.iterate(0, &(&1 + 1)) |> Enum.take(4) # => [0, 1, 2, 3] Stream.iterate(1, &(&1 * 2)) |> Enum.take(5) # => [1, 2, 4, 8, 16]

内包表記
elixir
for x <- 1..5, do: 2*x # => [2, 4, 6, 8, 10] for x <- [1,2,3,4,5], y <- [1,2,3,4,5], x > y, do: x*y # => [2, 3, 6, 4, 8, 12, 5, 10, 15, 20]

モジュール
elixir
defmodule SomeModule do # パブリック関数 # @example SomeModule.greet "taro" def greet(name) do message = make_message(name) IO.puts(message) end # プライベート関数 defp make_message(name) do "Hello, #{name}" end end

シジル(Sigil)
正規表現( ~r{...} )等の ~ から始まる文法のこと

文字列と文字のリスト
Elixirでは "..." で囲まれたものを文字列 '...' で囲まれたものを文字のリストとして扱います
文字のリスト( '...' )は実体としては整数のリスト
elixir
is_list 'hello' # => true is_list "hello" # => false

バイナリ
elixir
binary = << 1, 2, 3, 4 >> byte_size binary # => 4 bit_size binary # => 32 # ビット数の指定 bit_size << 1::size(2) >> # => 2 byte_size << 1::size(2) >> # => 1 bit_size << 1::size(8), 2::size(4) >> # => 12 byte_size << 1::size(8), 2::size(4) >> # => 2

プロセス

参考