feat: add docs/elixir.md (#587)
Co-authored-by: gowshwah <1099764281@qq.com>
This commit is contained in:
parent
cb5df68489
commit
8d60181b96
@ -51,6 +51,7 @@ Quick Reference
|
|||||||
[Docker](./docs/docker.md)<!--rehype:style=background: rgb(72 143 223);-->
|
[Docker](./docs/docker.md)<!--rehype:style=background: rgb(72 143 223);-->
|
||||||
[Dockerfile](./docs/dockerfile.md)<!--rehype:style=background: rgb(0 72 153);&class=tag&data-lang=Docker-->
|
[Dockerfile](./docs/dockerfile.md)<!--rehype:style=background: rgb(0 72 153);&class=tag&data-lang=Docker-->
|
||||||
[Django](./docs/django.md)<!--rehype:style=background: rgb(12 75 51);&class=contributing tag&data-lang=Python-->
|
[Django](./docs/django.md)<!--rehype:style=background: rgb(12 75 51);&class=contributing tag&data-lang=Python-->
|
||||||
|
[Elixir](./docs/elixir.md)<!--rehype:style=background: rgb(124 26 156);&class=contributing tag&data-lang=Elixir-->
|
||||||
[Flask](./docs/flask.md)<!--rehype:style=background: rgb(210 168 255);&class=contributing tag&data-lang=Python-->
|
[Flask](./docs/flask.md)<!--rehype:style=background: rgb(210 168 255);&class=contributing tag&data-lang=Python-->
|
||||||
[FastAPI](./docs/fastapi.md)<!--rehype:style=background: rgb(210 168 255);&class=contributing tag&data-lang=Python-->
|
[FastAPI](./docs/fastapi.md)<!--rehype:style=background: rgb(210 168 255);&class=contributing tag&data-lang=Python-->
|
||||||
[Flutter](./docs/flutter.md)<!--rehype:style=background: rgb(150 220 254);&class=contributing tag&data-lang=Dart-->
|
[Flutter](./docs/flutter.md)<!--rehype:style=background: rgb(150 220 254);&class=contributing tag&data-lang=Dart-->
|
||||||
|
1
assets/elixir.svg
Normal file
1
assets/elixir.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1711950965872" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4680" xmlns:xlink="http://www.w3.org/1999/xlink" width="1em" height="1em"><path d="M519.381333 967.722667c-164.693333 0-298.24-155.306667-298.24-346.88 0-156.928 118.314667-348.672 209.749334-465.493334 43.264-55.296 125.013333-99.072 125.013333-99.072s-41.898667 223.530667 71.808 312.277334c100.949333 78.805333 175.189333 181.333333 175.189333 271.488 0 180.565333-118.784 327.68-283.52 327.68z" fill="currentColor" p-id="4681"></path></svg>
|
After Width: | Height: | Size: 694 B |
487
docs/elixir.md
Normal file
487
docs/elixir.md
Normal file
@ -0,0 +1,487 @@
|
|||||||
|
Elixir 备忘清单
|
||||||
|
===
|
||||||
|
|
||||||
|
提供基本语法和方法的 Elixir 快速参考备忘单。
|
||||||
|
|
||||||
|
入门
|
||||||
|
------
|
||||||
|
|
||||||
|
### 安装Elixir
|
||||||
|
|
||||||
|
> 每个操作系统的安装说明可以在 elixir-lang.org 网站上 [Installing Elixir](http://elixir-lang.org/install.html) 部分找到。
|
||||||
|
> Elixir 自带了`iex`这样一个交互 shell,可以随时计算 Elixir 表达式的值,运行`iex`命令,继续输入几个简单的表达式试试:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
iex 2+3
|
||||||
|
5
|
||||||
|
iex 2+3 == 5
|
||||||
|
true
|
||||||
|
iex String.length("The quick brown fox jumps over the lazy dog")
|
||||||
|
43
|
||||||
|
```
|
||||||
|
|
||||||
|
### hello.exs
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
IO.puts("Hello world from Elixir")
|
||||||
|
```
|
||||||
|
|
||||||
|
Elixir 运行命令
|
||||||
|
|
||||||
|
```shell
|
||||||
|
$ elixir hello.exs
|
||||||
|
```
|
||||||
|
|
||||||
|
### 基本类型
|
||||||
|
>
|
||||||
|
> Elixir 支持多种基本类型:整数、浮点、布尔值、原子和字符串。其他数据类型,如列表和元组
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
iex> 1 # integer
|
||||||
|
iex> 0x1F # integer(支持二进制、八进制和十六进制的整数)
|
||||||
|
iex> 1.0 # float
|
||||||
|
iex> true # boolean
|
||||||
|
iex> :atom # atom / symbol
|
||||||
|
iex> "elixir" # string
|
||||||
|
iex> [1, 2, 3] # list
|
||||||
|
iex> {1, 2, 3} # tuple
|
||||||
|
```
|
||||||
|
|
||||||
|
### 基本算术
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
iex> 1 + 2
|
||||||
|
3
|
||||||
|
iex> 5 * 5
|
||||||
|
25
|
||||||
|
iex> 10 / 2
|
||||||
|
5.0
|
||||||
|
```
|
||||||
|
|
||||||
|
> 运算符`/`总是返回一个float。如果你想做整数除法或得到除法余数,你可以调用div和rem函数:
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
iex> div(10, 2)
|
||||||
|
5
|
||||||
|
iex> div 10, 2 # Elixir允许在调用需要一个或多个参数的函数时删除括号
|
||||||
|
5
|
||||||
|
iex> rem 10, 3
|
||||||
|
1
|
||||||
|
```
|
||||||
|
|
||||||
|
> 可以调用round函数来获取与给定浮点数最接近的整数,或者调用trunc函数来获取浮点数的整数部分
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
iex> round(3.58)
|
||||||
|
4
|
||||||
|
iex> trunc(3.58)
|
||||||
|
3
|
||||||
|
```
|
||||||
|
|
||||||
|
> 可以使用is_integer、is_float或is_number分别检查参数是否为integer、float或number类型
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
iex> is_integer(1)
|
||||||
|
true
|
||||||
|
iex> is_float(2.0)
|
||||||
|
true
|
||||||
|
iex> is_number(2.0)
|
||||||
|
false
|
||||||
|
```
|
||||||
|
|
||||||
|
### 布尔算术
|
||||||
|
>
|
||||||
|
> Elixir 提供了 `||`、`&&` 和 `!` 布尔操作符,它们支持任何类型的操作:
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
iex> -20 || true
|
||||||
|
-20
|
||||||
|
iex> false || 42
|
||||||
|
42
|
||||||
|
|
||||||
|
iex> 42 && true
|
||||||
|
true
|
||||||
|
iex> 42 && nil
|
||||||
|
nil
|
||||||
|
|
||||||
|
iex> !42
|
||||||
|
false
|
||||||
|
iex> !false
|
||||||
|
true
|
||||||
|
```
|
||||||
|
|
||||||
|
> 还有三个操作符(and、or、not),它们的第一个参数**必须是布尔类型**(true 和 false):
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
iex> true and 42
|
||||||
|
42
|
||||||
|
iex> false or true
|
||||||
|
true
|
||||||
|
iex> not false
|
||||||
|
true
|
||||||
|
iex> 42 and true
|
||||||
|
** (ArgumentError) argument error: 42
|
||||||
|
iex> not 42
|
||||||
|
** (ArgumentError) argument error
|
||||||
|
```
|
||||||
|
|
||||||
|
### 比较运算符
|
||||||
|
>
|
||||||
|
> 比较运算符 :`==`, `!=`, `===`, `!==`, `<=`, `>=`, `<` 和 `>`
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
iex> 1 > 2
|
||||||
|
false
|
||||||
|
iex> 1 != 2
|
||||||
|
true
|
||||||
|
iex> 2 == 2
|
||||||
|
true
|
||||||
|
iex> 2 <= 3
|
||||||
|
true
|
||||||
|
```
|
||||||
|
|
||||||
|
### 字符串插值与拼接
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
iex> name = "Sean"
|
||||||
|
iex> "Hello #{name}"
|
||||||
|
"Hello Sean"
|
||||||
|
|
||||||
|
iex> "Hello " <> "world!"
|
||||||
|
"Hello world!"
|
||||||
|
```
|
||||||
|
|
||||||
|
集合
|
||||||
|
------
|
||||||
|
>
|
||||||
|
> 列表(list)、元组(tuple)、关键字列表(keyword list)、映射(map)。
|
||||||
|
>
|
||||||
|
### 列表(List)
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
iex> [3.14, :pie, "Apple"]
|
||||||
|
[3.14, :pie, "Apple"]
|
||||||
|
|
||||||
|
iex> list = [3.14, :pie, "Apple"]
|
||||||
|
iex> [3.14, :pie, "Apple"]
|
||||||
|
iex> ["π" | list] # 列表的开头添加元素
|
||||||
|
["π", 3.14, :pie, "Apple"]
|
||||||
|
iex> list ++ ["Cherry"] # 列表的尾部添加元素/列表拼接
|
||||||
|
[3.14, :pie, "Apple", "Cherry"]
|
||||||
|
|
||||||
|
iex> hd [3.14, :pie, "Apple"] # 获取列表的头部元素
|
||||||
|
3.14
|
||||||
|
iex> tl [3.14, :pie, "Apple"] # 获取列表的尾部元素
|
||||||
|
[:pie, "Apple"]
|
||||||
|
```
|
||||||
|
|
||||||
|
### 元组(Tuple)
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
iex> {3.14, :pie, "Apple"}
|
||||||
|
{3.14, :pie, "Apple"}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 关键字列表(Keyword List)
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
iex> [foo: "bar", hello: "world"]
|
||||||
|
[foo: "bar", hello: "world"]
|
||||||
|
iex> [{:foo, "bar"}, {:hello, "world"}]
|
||||||
|
[foo: "bar", hello: "world"]
|
||||||
|
```
|
||||||
|
|
||||||
|
> 关键字列表非常重要,它有以下的特性:
|
||||||
|
|
||||||
|
- 键(key)都是原子(atom)
|
||||||
|
- 键(key)是有序的(定义后,顺序不会改变)
|
||||||
|
- 键(key)不必是唯一的
|
||||||
|
|
||||||
|
> 因为这些原因,关键字列表最常见的用法是作为参数传递给函数。
|
||||||
|
|
||||||
|
### 映射(Map)
|
||||||
|
|
||||||
|
> Elixir 的映射(maps)是键值对结构的第一选择,和关键字列表(keywords)不同,映射允许任意类型的数据作为键,而且数据并不严格排序。 你可以使用 %{} 来定义映射:
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
iex> map = %{:foo => "bar", "hello" => :world}
|
||||||
|
%{:foo => "bar", "hello" => :world}
|
||||||
|
iex> map[:foo]
|
||||||
|
"bar"
|
||||||
|
iex> map["hello"]
|
||||||
|
:world
|
||||||
|
```
|
||||||
|
|
||||||
|
模式匹配
|
||||||
|
------
|
||||||
|
>
|
||||||
|
> 模式匹配是 Elixir 很强大的特性,它允许我们匹配简单值、数据结构、甚至函数。
|
||||||
|
>
|
||||||
|
### 匹配操作符
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
# 匹配元组
|
||||||
|
iex> {a, b, c} = {:hello, "world", 42}
|
||||||
|
{:hello, "world", 42}
|
||||||
|
iex> a
|
||||||
|
:hello
|
||||||
|
iex> b
|
||||||
|
"world"
|
||||||
|
|
||||||
|
# 匹配列表
|
||||||
|
iex> [a, b, c] = [1, 2, 3]
|
||||||
|
[1, 2, 3]
|
||||||
|
iex> a
|
||||||
|
1
|
||||||
|
# 匹配列表的头部元素
|
||||||
|
iex> [head | tail] = [1, 2, 3]
|
||||||
|
[1, 2, 3]
|
||||||
|
iex> head
|
||||||
|
1
|
||||||
|
iex> tail
|
||||||
|
[2, 3]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Pin操作符
|
||||||
|
|
||||||
|
> pin 操作符,就是用已经绑定的值去匹配,而不是重新绑定一个新值。
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
iex> {x, ^x} = {2, 1}
|
||||||
|
{2, 1}
|
||||||
|
iex> x
|
||||||
|
2
|
||||||
|
|
||||||
|
# 使用下划线_忽略匹配的值
|
||||||
|
iex> [head | _] = [1, 2, 3]
|
||||||
|
[1, 2, 3]
|
||||||
|
iex> head
|
||||||
|
1
|
||||||
|
```
|
||||||
|
|
||||||
|
控制语句
|
||||||
|
------
|
||||||
|
>
|
||||||
|
> case, cond, and if
|
||||||
|
>
|
||||||
|
### case
|
||||||
|
>
|
||||||
|
> case允许我们将一个值与许多模式进行比较,直到找到匹配的模式:
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
iex> case {1, 2, 3} do
|
||||||
|
{4, 5, 6} ->
|
||||||
|
"This clause won't match"
|
||||||
|
{1, x, 3} ->
|
||||||
|
"This clause will match and bind x to 2 in this clause"
|
||||||
|
_ ->
|
||||||
|
"This clause would match any value"
|
||||||
|
end
|
||||||
|
"This clause will match and bind x to 2 in this clause"
|
||||||
|
|
||||||
|
# 还可以使用when指定额外的条件
|
||||||
|
iex> case {1, 2, 3} do
|
||||||
|
{1, x, 3} when x > 0 ->
|
||||||
|
"Will match"
|
||||||
|
_ ->
|
||||||
|
"Would match, if guard condition were not satisfied"
|
||||||
|
end
|
||||||
|
"Will match"
|
||||||
|
```
|
||||||
|
|
||||||
|
### cond
|
||||||
|
|
||||||
|
> 当我们需要匹配条件而不是值的时候,可以使用 cond,这和其他语言的 else if 或者 elsif 相似
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
iex> cond do
|
||||||
|
2 + 2 == 5 ->
|
||||||
|
"This will not be true"
|
||||||
|
2 * 2 == 3 ->
|
||||||
|
"Nor this"
|
||||||
|
1 + 1 == 2 ->
|
||||||
|
"But this will"
|
||||||
|
end
|
||||||
|
"But this will"
|
||||||
|
|
||||||
|
# 如果所有的条件都返回nil或false,则会引发一个错误(CondClauseError)。因此,需要添加一个final条件,等于true,它将始终匹配:
|
||||||
|
iex> cond do
|
||||||
|
2 + 2 == 5 ->
|
||||||
|
"This is never true"
|
||||||
|
2 * 2 == 3 ->
|
||||||
|
"Nor this"
|
||||||
|
true ->
|
||||||
|
"This is always true (equivalent to else)"
|
||||||
|
end
|
||||||
|
"This is always true (equivalent to else)"
|
||||||
|
```
|
||||||
|
|
||||||
|
### if/unless
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
iex> if true do
|
||||||
|
"This works!"
|
||||||
|
end
|
||||||
|
"This works!"
|
||||||
|
|
||||||
|
iex> unless true do
|
||||||
|
"This will never be seen"
|
||||||
|
end
|
||||||
|
nil
|
||||||
|
|
||||||
|
# if...else...
|
||||||
|
iex> if nil do
|
||||||
|
"This won't be seen"
|
||||||
|
else
|
||||||
|
"This will"
|
||||||
|
end
|
||||||
|
"This will"
|
||||||
|
|
||||||
|
# 关于Elixir中变量的作用域:如果在if、case和类似的构造中声明或更改了任何变量,则声明和更改将只在构造中可见。
|
||||||
|
iex> x = 1
|
||||||
|
1
|
||||||
|
if true do
|
||||||
|
x = x + 1
|
||||||
|
end
|
||||||
|
2
|
||||||
|
iex> x
|
||||||
|
1
|
||||||
|
|
||||||
|
# 如果要更改值,则必须从if返回值:
|
||||||
|
iex> x = 1
|
||||||
|
1
|
||||||
|
iex> x = if true do
|
||||||
|
x + 1
|
||||||
|
else
|
||||||
|
x
|
||||||
|
end
|
||||||
|
2
|
||||||
|
```
|
||||||
|
|
||||||
|
函数
|
||||||
|
------
|
||||||
|
|
||||||
|
### 匿名函数
|
||||||
|
>
|
||||||
|
> 使用 fn 和 end 关键字来定义匿名函数,在这两者之间,可以定义任意数量的参数和函数体,它们用 -> 分隔开。
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
iex> sum = fn (a, b) -> a + b end
|
||||||
|
iex> sum.(2, 3)
|
||||||
|
5
|
||||||
|
|
||||||
|
# 可以使用 & 语法来简化匿名函数的定义:
|
||||||
|
iex> sum = &(&1 + &2)
|
||||||
|
iex> sum.(2, 3)
|
||||||
|
5
|
||||||
|
```
|
||||||
|
|
||||||
|
### 闭包
|
||||||
|
>
|
||||||
|
> 匿名函数去引用外部的变量,这通常被称为闭包。
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
iex> double = fn a -> add.(a, a) end
|
||||||
|
#Function<6.71889879/1 in :erl_eval.expr/5>
|
||||||
|
double.(2)
|
||||||
|
4
|
||||||
|
```
|
||||||
|
|
||||||
|
> 闭包与守卫
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
iex> f = fn
|
||||||
|
x, y when x > 0 -> x + y
|
||||||
|
x, y -> x * y
|
||||||
|
end
|
||||||
|
|
||||||
|
iex> f.(1, 3)
|
||||||
|
4
|
||||||
|
iex> f.(-1, 3)
|
||||||
|
-3
|
||||||
|
```
|
||||||
|
|
||||||
|
### 命名函数
|
||||||
|
>
|
||||||
|
> 命名函数是通过 def 关键字定义在某个模块中
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
defmodule Greeter do
|
||||||
|
def hello(name) do
|
||||||
|
"Hello, " <> name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
iex> Greeter.hello("Sean")
|
||||||
|
"Hello, Sean"
|
||||||
|
|
||||||
|
# 简写为一行:
|
||||||
|
defmodule Greeter do
|
||||||
|
def hello(name), do: "Hello, " <> name
|
||||||
|
end
|
||||||
|
|
||||||
|
# 私有函数
|
||||||
|
defmodule Greeter do
|
||||||
|
def hello(name), do: phrase <> name
|
||||||
|
defp phrase, do: "Hello, " # 使用defp来定义私有函数
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
> 函数的默认参数:使用`\\`来定义默认参数
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
defmodule Greeter do
|
||||||
|
def hello(name, language_code \\ "en") do
|
||||||
|
phrase(language_code) <> name
|
||||||
|
end
|
||||||
|
|
||||||
|
defp phrase("en"), do: "Hello, "
|
||||||
|
defp phrase("es"), do: "Hola, "
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
Enumerables 与 Streams
|
||||||
|
------
|
||||||
|
>
|
||||||
|
> Elixir 提供了 Enum 和 Stream 两个模块,用于处理集合。
|
||||||
|
>
|
||||||
|
### Enum
|
||||||
|
>
|
||||||
|
> Enum 模块提供了对集合的常用操作,如 map、filter、reduce、sort、chunk、join、into 等。
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
iex> Enum.map([1, 2, 3], fn x -> x * 2 end)
|
||||||
|
[2, 4, 6]
|
||||||
|
iex> Enum.map(%{1 => 2, 3 => 4}, fn {k, v} -> k * v end)
|
||||||
|
[2, 12]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Stream
|
||||||
|
>
|
||||||
|
> 作为Enum的替代品,Elixir提供了支持懒惰操作的Stream模块
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
iex> 1..100_000 |> Stream.map(&(&1 * 3)) |> Stream.filter(odd?) |> Enum.sum()
|
||||||
|
7500000000
|
||||||
|
```
|
||||||
|
|
||||||
|
> 流文件操作
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
iex> stream = File.stream!("path/to/file")
|
||||||
|
%File.Stream{
|
||||||
|
line_or_bytes: :line,
|
||||||
|
modes: [:raw, :read_ahead, :binary],
|
||||||
|
path: "path/to/file",
|
||||||
|
raw: true
|
||||||
|
}
|
||||||
|
Enum.take(stream, 10)
|
||||||
|
|
||||||
|
# 上面的例子将提取所选文件的前10行。这意味着流对于处理大型文件甚至是网络资源等慢速资源非常有用。
|
||||||
|
```
|
||||||
|
|
||||||
|
另见
|
||||||
|
----
|
||||||
|
|
||||||
|
- [Elixir 官方](https://elixir-lang.org/) _(elixir-lang.org)_
|
||||||
|
- [Elixir School](https://elixirschool.com/) _(elixirschool.com)_
|
Loading…
x
Reference in New Issue
Block a user