Elixircheatsheet
贡献者:BAI
Getting started
Hello world
ELIXIR# hello.exsdefmodule Greeter do def greet(name) do message = "Hello, " <> name <> "!" IO.puts message endendGreeter.greet("world")
BASHelixir hello.exs# Hello, world!
变量
ELIXIRage = 23
Map
ELIXIRuser = %{ name: "John", city: "Melbourne"}
ELIXIRIO.puts "Hello, " <> user.name
List
ELIXIRusers = [ "Tom", "Dick", "Harry" ]
ELIXIREnum.map(users, fn user -> IO.puts "Hello " <> userend)
Piping
ELIXIRsource|> transform(:hello)|> print()
ELIXIRprint(transform(source, :hello))
上面两个等价
模式匹配
ELIXIRuser = %{name: "Tom", age: 23}%{name: username} = user
上面语境将 username
赋值为 "TOM"
函数中的模式匹配
ELIXIRdef greet(%{name: username}) do IO.puts "Hello, " <> usernameenduser = %{name: "Tom", age: 23}
模式匹配也可以在函数参数中使用
控制流
If
ELIXIRif false do "This will never be seen"else "This will"end
Case
ELIXIRcase {1, 2, 3} do {4, 5, 6} -> "This clause won't match" {1, x, 3} -> "This will match and bind x to 2" _ -> "This will match any value"end
Cond
ELIXIRcond do 1 + 1 == 3 -> "I will never be seen" 2 * 5 == 12 -> "Me neither" true -> "But I will (this is essentially an else)"end
Errors
ELIXIRtry do throw(:hello)catch message -> "Got #{message}."after IO.puts("I'm the after clause.")end
类型
原始类型
Sample | Type |
---|---|
nil | Nil/null |
true / false | Boolean |
--- | --- |
?a | Integer (ASCII) |
23 | Integer |
3.14 | Float |
--- | --- |
'hello' | Charlist |
<<2, 3>> | Binary |
"hello" | Binary string |
:hello | Atom |
--- | --- |
[a, b] | List |
{a, b} | Tuple |
--- | --- |
%{a: "hello"} | Map |
%MyStruct{a: "hello"} | Struct |
fn -> ... end | Function |
类型检查
ELIXIRis_atom/1is_bitstring/1is_boolean/1is_function/1is_function/2is_integer/1is_float/1
ELIXIRis_binary/1is_list/1is_map/1is_tuple/1
ELIXIRis_nil/1is_number/1is_pid/1is_port/1is_reference/1
操作符
ELIXIRleft != right # equalleft !== right # matchleft ++ right # concat listsleft <> right # concat string/binaryleft =~ right # regexp
模块
导入
ELIXIRrequire Redux # compiles a moduleimport Redux # compiles, and you can use without the `Redux.` prefixuse Redux # compiles, and runs Redux.__using__/1use Redux, async: trueimport Redux, only: [duplicate: 2]import Redux, only: :functionsimport Redux, only: :macrosimport Foo.{Bar, Baz}
别名(Alias)
ELIXIRalias Foo.Bar, as: Baralias Foo.Bar # same as abovealias Foo.{Bar, Baz}
字符串
常用函数
ELIXIRimport String
ELIXIRstr = "hello"str |> length() # → 5str |> codepoints() # → ["h", "e", "l", "l", "o"]str |> slice(2..-1) # → "llo"str |> split(" ") # → ["hello"]str |> capitalize() # → "Hello"str |> match(regex)
检查对象
ELIXIRinspect(object, opts \\ [])
ELIXIRvalue |> IO.inspect()
ELIXIRvalue |> IO.inspect(label: "value")
数字
操作符
ELIXIRabs(n)round(n)rem(a, b) # remainder (modulo)div(a, b) # integer division
Float
ELIXIRimport Float
ELIXIRn = 10.3
ELIXIRn |> ceil() # → 11.0n |> ceil(2) # → 11.30n |> to_string() # → "1.030000+e01"n |> to_string([decimals: 2, compact: true])
ELIXIRFloat.parse("34") # → { 34.0, "" }
Integer
ELIXIRimport Integer
ELIXIRn = 12
ELIXIRn |> digits() # → [1, 2]n |> to_charlist() # → '12'n |> to_string() # → "12"n |> is_even()n |> is_odd()
ELIXIR# Different base:n |> digits(2) # → [1, 1, 0, 0]n |> to_charlist(2) # → '1100'n |> to_string(2) # → "1100"
ELIXIRparse("12") # → {12, ""}undigits([1, 2]) # → 12
Type 转换
ELIXIRFloat.parse("34.1") # → {34.1, ""}Integer.parse("34") # → {34, ""}
ELIXIRFloat.to_string(34.1) # → "3.4100e+01"Float.to_string(34.1, [decimals: 2, compact: true]) # → "34.1"
Map
定义
ELIXIRm = %{name: "hi"} # atom keys (:name)m = %{"name" => "hi"} # string keys ("name")
更改
ELIXIRimport Map
ELIXIRm = %{m | name: "yo"} # key must exist
ELIXIRm |> put(:id, 2) # → %{id: 2, name: "hi"}m |> put_new(:id, 2) # only if `id` doesn't exist (`||=`)
ELIXIRm |> put(:b, "Banana")m |> merge(%{b: "Banana"})m |> update(:a, &(&1 + 1))m |> update(:a, fun a -> a + 1 end)
ELIXIRm |> get_and_update(:a, &(&1 || "default"))# → {old, new}
删除
ELIXIRm |> delete(:name) # → %{}m |> pop(:name) # → {"John", %{}}
读取
ELIXIRm |> get(:id) # → 1m |> keys() # → [:id, :name]m |> values() # → [1, "hi"]
ELIXIRm |> to_list() # → [id: 1, name: "hi"] # → []
深层读取
ELIXIRput_in(map, [:b, :c], "Banana")put_in(map[:b][:c], "Banana") # via macros
ELIXIRget_and_update_in(users, ["john", :age], &{&1, &1 + 1})
从 List 中构建
ELIXIRMap.new([])Map.new([a: 1, b: 2])Map.new([:a, :b], fn x -> {x, x} end) # → %{a: :a, b: :b}
List
ELIXIRimport List
ELIXIRl = [ 1, 2, 3, 4 ]
ELIXIRl = l ++ [5] # push (append)l = [ 0 | list ] # unshift (prepend)
ELIXIRl |> first()l |> last()
ELIXIRl |> flatten()l |> flatten(tail)
详见 Enum.
Enum
用法
ELIXIRimport Enum
ELIXIRlist = [:a, :b, :c]
ELIXIRlist |> at(0) # → :alist |> count() # → 3list |> empty?() # → falselist |> any?() # → true
ELIXIRlist |> concat([:d]) # → [:a, :b, :c, :d]
也可以用 Stream 代替
Map 和 Reduce
ELIXIRlist |> reduce(fn)list |> reduce(acc, fn)list |> map(fn)list |> reject(fn)list |> any?(fn)list |> empty?(fn)
ELIXIR[1, 2, 3, 4]|> Enum.reduce(0, fn(x, acc) -> x + acc end)
Tuple
Tuple
ELIXIRimport Tuple
ELIXIRt = { :a, :b }
ELIXIRt |> elem(1) # like tuple[1]t |> put_elem(index, value)t |> tuple_size()
带关键字的 List
ELIXIRlist = [{ :name, "John" }, { :age, 15 }]list[:name]
ELIXIR# For string-keyed keyword listslist = [{"size", 2}, {"type", "shoe"}]List.keyfind(list, "size", 0) # → {"size", 2}
函数
Lambda
ELIXIRsquare = fn n -> n*n endsquare.(20)
& 标识符
ELIXIRsquare = &(&1 * &1)square.(20)square = &Math.square/1
函数执行
ELIXIRfun.(args)apply(fun, args)apply(module, fun, args)
函数头
ELIXIRdef join(a, b \\ nil)def join(a, b) when is_nil(b) do: adef join(a, b) do: a <> b
结构体
结构体
ELIXIRdefmodule User do defstruct name: "", age: nilend%User{name: "John", age: 20}%User{}.struct # → User
详见: Structs
协议(Protocol)
定义
ELIXIRdefprotocol Blank do @doc "Returns true if data is considered blank/empty" def blank?(data)end
ELIXIRdefimpl Blank, for: List do def blank?([]), do: true def blank?(_), do: falseendBlank.blank?([]) # → true
Any
..defimpl Blank, for: Any do ... enddefmodule User do @derive Blank # Falls back to Any defstruct name: ""end
示例
Enumerable
andEnum.map()
Inspect
andinspect()
推导式
For
ELIXIRfor n <- [1, 2, 3, 4], do: n * nfor n <- 1..4, do: n * n
ELIXIRfor {key, val} <- %{a: 10, b: 20}, do: val# → [10, 20]
ELIXIRfor {key, val} <- %{a: 10, b: 20}, into: %{}, do: {key, val*val}
条件
ELIXIRfor n <- 1..10, rem(n, 2) == 0, do: n# → [2, 4, 6, 8, 10]
复杂的示例
ELIXIRfor dir <- dirs, file <- File.ls!(dir), # 嵌套 path = Path.join(dir, file), # 调用 File.regular?(path) do # 条件判断 IO.puts(file)end
Misc
元编程
ELIXIR__MODULE____MODULE__.__info__@after_compile __MODULE__def __before_compile__(env)def __after_compile__(env, _bytecode)def __using__(opts) # invoked on `use`@on_definition {__MODULE__, :on_def}def on_def(_env, kind, name, args, guards, body)@on_load :load_checkdef load_check
正则
ELIXIRexp = ~r/hello/exp = ~r/hello/i"hello world" =~ exp
Sigil
ELIXIR~r/regexp/~w(list of strings)~s|strings with #{interpolation} and \x20 escape codes|~S|no interpolation and no escapes|~c(charlist)
允许的字符: /
|
"
'
(
[
{
<
"""
.
详见: Sigils
类型 Spec
ELIXIR@spec round(number) :: integer@type number_with_remark :: {number, String.t}@spec add(number, number) :: number_with_remark
行为
ELIXIRdefmodule Parser do @callback parse(String.t) :: any @callback extensions() :: [String.t]end
ELIXIRdefmodule JSONParser do @behaviour Parser def parse(str), do: # ... parse JSON def extensions, do: ["json"]end
详见: Module