diff --git a/docs/elixir.md b/docs/elixir.md index 9c3e7de..ee9a761 100644 --- a/docs/elixir.md +++ b/docs/elixir.md @@ -6,20 +6,22 @@ Elixir 备忘清单 入门 ------ -### 安装Elixir +### 安装 Elixir + -> 每个操作系统的安装说明可以在 elixir-lang.org 网站上 [Installing Elixir](http://elixir-lang.org/install.html) 部分找到。 -> Elixir 自带了`iex`这样一个交互 shell,可以随时计算 Elixir 表达式的值,运行`iex`命令,继续输入几个简单的表达式试试: +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") +iex String.length("快速的狐狸跳过了懒惰的狗") 43 ``` +每个操作系统的文档可以在[官网](https://elixir-lang.org)网站上 [Installing Elixir](http://elixir-lang.org/install.html) 部分找到 + ### hello.exs ```elixir @@ -33,21 +35,128 @@ $ elixir hello.exs ``` ### 基本类型 -> -> Elixir 支持多种基本类型:整数、浮点、布尔值、原子和字符串。其他数据类型,如列表和元组 + + +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 +# integer 整数 +iex> 1 +# integer(支持2进制、8进制和16进制的整数) +iex> 0x1F +# float +iex> 1.0 +# boolean +iex> true +# atom / symbol +iex> :atom +# string +iex> "elixir" +# list +iex> [1, 2, 3] +# tuple +iex> {1, 2, 3} +``` + +### 注释 + +```elixir +# 这是一个单行注释 +``` + +### 字符串插值与拼接 + +```elixir +iex> name = "Sean" +iex> "Hello #{name}" +"Hello Sean" + +iex> "Hello " <> "world!" +"Hello world!" +``` + +### 变量和模式匹配 + +```elixir +x = 1 +# => x 现在等于 1 + +{a, b} = {1, 2} +# => a 等于 1,b 等于 2 +``` + +在 Elixir 中,使用 `=` 来进行赋值操作,但实际上是模式匹配。左边是模式,右边是值 + +### 原子(Atoms) + +```elixir +:ok +``` + +原子是常量,它们的名称就是它们的值 + +### 列表(Lists) + +```elixir +list = [1, 2, 3] +``` + +### 元组(Tuples) + +```elixir +tuple = {:ok, "value"} +``` + +### 函数定义 + +```elixir +defmodule MyModule do + def my_function(parameter) do + # 函数体 + end +end +``` + +### 匿名函数 + +```elixir +add = fn a, b -> a + b end +``` + +### 控制结构 + + +`if/else` + +```elixir +if x > 0 do + "Positive" +else + "Non-positive" +end +``` + +`case` + +```elixir +case {1, 2} do + {1, x} -> "Matched #{x}" + _ -> "Not matched" +end +``` + +`cond` + +```elixir +cond do + x > 2 -> "Greater than 2" + x == 2 -> "Equal to 2" + true -> "Less than 2" +end ``` ### 基本算术 + ```elixir iex> 1 + 2 @@ -58,18 +167,23 @@ iex> 10 / 2 5.0 ``` -> 运算符`/`总是返回一个float。如果你想做整数除法或得到除法余数,你可以调用div和rem函数: +运算符`/`总是返回一个 float。如果你想做整数除法或得到除法余数,你可以调用 div 和 rem 函数: ```elixir iex> div(10, 2) 5 -iex> div 10, 2 # Elixir允许在调用需要一个或多个参数的函数时删除括号 +``` + +允许在调用需要一个或多个参数的函数时删除括号 + +```elixir +iex> div 10, 2 5 iex> rem 10, 3 1 ``` -> 可以调用round函数来获取与给定浮点数最接近的整数,或者调用trunc函数来获取浮点数的整数部分 +可以调用 round 函数来获取与给定浮点数最接近的整数,或者调用 trunc 函数来获取浮点数的整数部分 ```elixir iex> round(3.58) @@ -78,7 +192,7 @@ iex> trunc(3.58) 3 ``` -> 可以使用is_integer、is_float或is_number分别检查参数是否为integer、float或number类型 +可以使用 is_integer、is_float 或 is_number 分别检查参数是否为 integer、float 或 number 类型 ```elixir iex> is_integer(1) @@ -90,8 +204,9 @@ false ``` ### 布尔算术 -> -> Elixir 提供了 `||`、`&&` 和 `!` 布尔操作符,它们支持任何类型的操作: + + +Elixir 提供了 `||`、`&&` 和 `!` 布尔操作符,它们支持任何类型的操作: ```elixir iex> -20 || true @@ -110,7 +225,7 @@ iex> !false true ``` -> 还有三个操作符(and、or、not),它们的第一个参数**必须是布尔类型**(true 和 false): +还有三个操作符(and、or、not),它们的第一个参数**必须是布尔类型**(true 和 false): ```elixir iex> true and 42 @@ -125,9 +240,25 @@ iex> not 42 ** (ArgumentError) argument error ``` +### 模块和函数导入 + +```elixir +import List, only: [duplicate: 2] +``` + +### 管道操作符 + +```elixir +result = data + |> process1() + |> process2() +``` + +`|>` 用于链式调用函数,将前一个函数的结果作为下一个函数的第一个参数 + ### 比较运算符 -> -> 比较运算符 :`==`, `!=`, `===`, `!==`, `<=`, `>=`, `<` 和 `>` + +比较运算符 :`==`, `!=`, `===`, `!==`, `<=`, `>=`, `<` 和 `>` ```elixir iex> 1 > 2 @@ -140,23 +271,14 @@ 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"] @@ -164,14 +286,34 @@ iex> [3.14, :pie, "Apple"] iex> list = [3.14, :pie, "Apple"] iex> [3.14, :pie, "Apple"] -iex> ["π" | list] # 列表的开头添加元素 +``` + +列表的开头添加元素 + +```elixir +iex> ["π" | list] ["π", 3.14, :pie, "Apple"] -iex> list ++ ["Cherry"] # 列表的尾部添加元素/列表拼接 +``` + +列表的尾部添加元素/列表拼接 + +```elixir +iex> list ++ ["Cherry"] [3.14, :pie, "Apple", "Cherry"] -iex> hd [3.14, :pie, "Apple"] # 获取列表的头部元素 +``` + +获取列表的头部元素 + +```elixir +iex> hd [3.14, :pie, "Apple"] 3.14 -iex> tl [3.14, :pie, "Apple"] # 获取列表的尾部元素 +``` + +获取列表的尾部元素 + +```elixir +iex> tl [3.14, :pie, "Apple"] [:pie, "Apple"] ``` @@ -191,17 +333,17 @@ iex> [{:foo, "bar"}, {:hello, "world"}] [foo: "bar", hello: "world"] ``` -> 关键字列表非常重要,它有以下的特性: +关键字列表非常重要,它有以下的特性: - 键(key)都是原子(atom) - 键(key)是有序的(定义后,顺序不会改变) - 键(key)不必是唯一的 -> 因为这些原因,关键字列表最常见的用法是作为参数传递给函数。 +因为这些原因,常见的用法是作为参数传递给函数 ### 映射(Map) -> Elixir 的映射(maps)是键值对结构的第一选择,和关键字列表(keywords)不同,映射允许任意类型的数据作为键,而且数据并不严格排序。 你可以使用 %{} 来定义映射: +Elixir 的映射(maps)是键值对结构的第一选择,和关键字列表(keywords)不同,映射允许任意类型的数据作为键,而且数据并不严格排序。 你可以使用 %{} 来定义映射: ```elixir iex> map = %{:foo => "bar", "hello" => :world} @@ -214,26 +356,34 @@ iex> map["hello"] 模式匹配 ------ + > > 模式匹配是 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 @@ -242,17 +392,20 @@ iex> tail [2, 3] ``` -### Pin操作符 +### Pin 操作符 -> pin 操作符,就是用已经绑定的值去匹配,而不是重新绑定一个新值。 +pin 操作符,就是用已经绑定的值去匹配,而不是重新绑定一个新值。 ```elixir iex> {x, ^x} = {2, 1} {2, 1} iex> x 2 +``` -# 使用下划线_忽略匹配的值 +### 使用下划线 `_` 忽略匹配的值 + +```elixir iex> [head | _] = [1, 2, 3] [1, 2, 3] iex> head @@ -261,37 +414,89 @@ iex> head 控制语句 ------ -> -> case, cond, and if -> + +### if/else/end + +```elixir +if condition do + # 条件成立时执行的代码 +else + # 条件不成立时执行的代码 +end +``` + +### case/end + +```elixir +case expression do + pattern1 -> # 匹配 pattern1 时执行的代码 + pattern2 -> # 匹配 pattern2 时执行的代码 + _ -> # 其他情况执行的代码 +end +``` + +### cond/end + +```elixir +cond do + condition1 -> # 条件1成立时执行的代码 + condition2 -> # 条件2成立时执行的代码 + true -> # 如果没有任何条件成立,执行这里的代码 +end +``` + +### unless/do/end + +```elixir +unless condition do + # 条件为假时执行的代码 +end +``` + +### try/rescue/end + +```elixir +try do + # 可能会引发异常的代码 +rescue + pattern1 -> # 匹配 pattern1 的异常处理代码 + pattern2 -> # 匹配 pattern2 的异常处理代码 + _ -> # 其他异常处理代码 +end +``` + ### 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" + "该子句将匹配并绑定 x 到该子句中的 2" _ -> "This clause would match any value" end -"This clause will match and bind x to 2 in this clause" +"该子句将匹配并绑定 x 到该子句中的 2" +``` -# 还可以使用when指定额外的条件 +还可以使用when指定额外的条件 + +```elixir 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 相似 +当我们需要根据条件进行匹配而不是值时,类似于其他语言的 `else if` 或 `elsif`,可以使用 `cond` 控制结构。 ```elixir iex> cond do @@ -303,41 +508,27 @@ iex> cond do "But this will" end "But this will" +``` -# 如果所有的条件都返回nil或false,则会引发一个错误(CondClauseError)。因此,需要添加一个final条件,等于true,它将始终匹配: +如果所有的条件都返回 `nil` 或 `false`,则会引发一个错误(CondClauseError)。因此,需要添加一个 `final` 条件,等于 `true`,它将始终匹配: + +```elixir iex> cond do 2 + 2 == 5 -> "This is never true" 2 * 2 == 3 -> "Nor this" true -> - "This is always true (equivalent to else)" + "这始终为真(等同于 else)" end -"This is always true (equivalent to else)" +"这始终为真(等同于 else)" ``` -### if/unless +### 变量的作用域 + +如果在if、case和类似的构造中声明或更改了任何变量,则声明和更改将只在构造中可见。 ```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 @@ -346,8 +537,11 @@ end 2 iex> x 1 +``` -# 如果要更改值,则必须从if返回值: +如果要更改值,则必须从if返回值: + +```elixir iex> x = 1 1 iex> x = if true do