Skip to content

Commit bb10eb6

Browse files
committed
daily update
1 parent 3122eea commit bb10eb6

File tree

4 files changed

+79
-55
lines changed

4 files changed

+79
-55
lines changed

1-intro.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
现在开始吧!
1717

18-
>如果你发现本手册有错误,请帮忙开issue或发pull request
18+
>如果你发现本手册有错误,请帮忙开_issue_讨论或发_pull request_
1919
2020
## 1.1-安装包
2121
在各个平台上最方便的安装方式是相应平台的安装包。

2-basic-types.md

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ iex> 5 * 5
2727
iex> 10 / 2
2828
5.0
2929
```
30+
3031
>```10 / 2```返回了一个浮点型的5.0而非整型的5,这是预期的。
3132
在Elixir中,```/```运算符总是返回浮点型数值。
3233

@@ -234,7 +235,7 @@ iex> [1, true, 2, false, 3, true] -- [true, false]
234235
[1, 2, 3, true]
235236
```
236237

237-
本教程将多次涉及列表的头(head)和尾(tail)的概念。
238+
本教程将多次涉及列表头(head)和尾(tail)的概念。
238239
列表的头指的是第一个元素,而尾指的是除了第一个元素以外,其它元素组成的列表。
239240
它们分别可以用函数```hd/1``````tl/1```从原列表中取出:
240241
```elixir
@@ -252,15 +253,15 @@ iex> hd []
252253
```
253254

254255
## 2.7-元组
255-
Elixir使用大括号(花括号)定义元组(tuples)。类似列表,元组也可以承载任意类型的数据
256+
Elixir使用大括号(花括号)定义元组(tuples)。类似列表,元组也可以承载任意类型的数据:
256257
```elixir
257258
iex> {:ok, "hello"}
258259
{:ok, "hello"}
259260
iex> tuple_size {:ok, "hello"}
260261
2
261262
```
262-
元组使用连续的内存空间存储数据
263-
这意味着可以很方便地使用索引访问元组数据,以及获取元组大小(索引从0开始):
263+
元组使用 ***连续的内存空间*** 存储数据
264+
这意味着可以很方便地使用索引访问元组数据,以及获取元组大小(索引从0开始):
264265
```elixir
265266
iex> tuple = {:ok, "hello"}
266267
{:ok, "hello"}
@@ -288,7 +289,7 @@ iex> tuple
288289
## 2.8-列表还是元组?
289290
列表与元组的区别:列表在内存中是以链表的形式存储的,一个元素指向下一个元素,
290291
然后再下一个...直到到达列表末尾。
291-
我们称这样的一对(元素值+指向下一个元素的指针)为列表的一个单元(cons cell)。
292+
我们称这样的一对数据(元素值指向下一个元素的指针)为列表的一个单元(cons cell)。
292293

293294
用Elixir语法表示这种模式:
294295
```elixir
@@ -306,16 +307,17 @@ iex> list ++ [4]
306307
[1, 2, 3, 4]
307308
```
308309

309-
上面例子中第一条语句是前置拼接操作,执行起来很快。
310-
因为它只是简单地添加了一个新列表单元,它指向原先列表头部。而原先的列表没有任何变化。
311-
第二条语句是后缀拼接操作,执行速度较慢。
310+
上面例子中第一条语句是 __前置__ 拼接操作,执行起来很快。
311+
因为它只是简单地添加了一个新列表单元,它的尾指针指向原先列表头部。而原先的列表没有任何变化。
312+
313+
第二条语句是 __后缀__ 拼接操作,执行速度较慢。
312314
这是因为它 **重建** 了原先的列表,让原先列表的末尾元素指向那个新元素。
313315

314-
而另一方面,元组在内存中是连续存储的。
316+
另一方面,元组在内存中是连续存储的。
315317
这意味着获取元组大小,或者使用索引访问元组元素的操作十分快速。
316-
但是元组在修改或添加元素时开销很大,因为这些操作会在内存中对元组的进行整体复制。
318+
但是元组在修改或添加元素时开销很大,因为这些操作会在内存中对元组的进行整体复制。
317319

318-
这些讨论告诉我们当如何在不同的情况下选择使用不同的数据结构。
320+
这些讨论告诉我们当如何在不同的情况下选择使用不同的数据结构。
319321

320322
函数常用元组来返回多个信息。如```File.read/1```,它读取文件内容,返回一个元组:
321323
```elixir
@@ -330,7 +332,7 @@ iex> File.read("path/to/unknown/file")
330332
如果路径无效,函数也将返回一个元组,其首元素是原子```:error```,第二个元素是错误信息。
331333

332334
大多数情况下,Elixir会引导你做正确的事。
333-
如有个叫```elem/2```的函数,它使用索引来访问一个元组元素。
335+
比如有个叫```elem/2```的函数,它使用索引来访问一个元组元素。
334336
这个函数没有相应的列表版本,因为根据存储机制,列表不适用通过索引来访问:
335337
```elixir
336338
iex> tuple = {:ok, "hello"}
@@ -340,11 +342,10 @@ iex> elem(tuple, 1)
340342
```
341343

342344
当需要计算某数据结构包含的元素个数时,Elixir遵循一个简单的规则:
343-
如果操作在常数时间内完成(答案是提前算好的),这样的函数通常被命名为 _*size_
344-
而如果操作需要显式计数,那么该函数通常命名为 _*length_
345+
如果操作在常数时间内完成(答案是提前算好的),这样的函数通常被命名为 ```*size```
346+
而如果操作需要显式计数,那么该函数通常命名为 ```*length```
345347

346-
例如,目前讲到过的4个计数函数:```byte_size/1```
347-
(用来计算字符串有多少字节),```tuple_size/1```
348+
例如,目前讲到过的4个计数函数:```byte_size/1```(用来计算字符串有多少字节),```tuple_size/1```
348349
(用来计算元组大小),```length/1```(计算列表长度)
349350
以及```String.length/1```(计算字符串中的字符数)。
350351

3-basic-ops.md

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,51 @@
11
3-基本运算符
22
============
3-
通过前几章我们知道Elixir提供了 +,-,*,/ 4个算术运算符,外加整数除法函数div/2和取余函数rem/2。
4-
Elixir还提供了++和--运算符来操作列表:
5-
```
3+
4+
通过前几章的学习,我们知道Elixir提供了 ```+,-,*,/``` 4个算术运算符,外加整数除法函数```div/2```
5+
取余函数```rem/2```
6+
Elixir还提供了```++``````--```运算符来操作列表:
7+
```elixir
68
iex> [1,2,3] ++ [4,5,6]
79
[1,2,3,4,5,6]
810
iex> [1,2,3] -- [2]
911
[1,3]
1012
```
11-
使用<>进行字符串拼接:
12-
```
13+
14+
使用```<>```进行字符串拼接:
15+
```elixir
1316
iex> "foo" <> "bar"
1417
"foobar"
1518
```
16-
Elixir还提供了三个布尔运算符:or,and和not。这三个运算符只接受布尔值作为第一个参数:
17-
```
19+
20+
Elixir还提供了三个布尔运算符:```or,and,not```。这三个运算符只接受布尔值作为 *第一个* 参数:
21+
```elixir
1822
iex> true and true
1923
true
2024
iex> false or is_atom(:example)
2125
true
2226
```
27+
2328
如果提供了非布尔值作为第一个参数,会报异常:
24-
```
29+
```elixir
2530
iex> 1 and true
2631
** (ArgumentError) argument error
2732
```
2833

29-
or和and可短路,即它们仅在第一个参数无法决定整体结果的情况下才执行第二个参数:
30-
```
34+
运算符```or``````and```可短路,即它们仅在第一个参数无法决定整体结果的情况下才执行第二个参数:
35+
```elixir
3136
iex> false and error("This error will never be raised")
3237
false
3338

3439
iex> true or error("This error will never be raised")
3540
true
3641
```
37-
>如果你是Erlang程序员,Elixir中的and和or其实就是andalso和orelse运算符。
3842

39-
除了这几个布尔运算符,Elixir还提供||,&&和!运算符。它们可以接受任意类型的参数值。
40-
在使用这些运算符时,除了false和nil的值都被视作true:
41-
```
43+
>如果你是Erlang程序员,Elixir中的```and``````or```其实就是```andalso``````orelse```运算符。
44+
45+
除了这几个布尔运算符,Elixir还提供```||``````&&``````!```运算符。它们可以接受任意类型的参数值。
46+
在使用这些运算符时,除了 false 和 nil 的值都被视作 true:
47+
48+
```elixir
4249
# or
4350
iex> 1 || true
4451
1
@@ -60,10 +67,12 @@ iex> !nil
6067
true
6168
```
6269

63-
根据经验,当参数返回的是布尔时,使用and,or和not;如果非布尔值,用&&,||和!。
70+
根据经验,当参数确定是布尔时,使用```and``````or``````not```
71+
如果非布尔值(或不确定是不是),用```&&``````||``````!```
6472

65-
Elixir还提供了==,!=,===,!==,<=,>=,<和>这些比较运算符:
66-
```
73+
Elixir还提供了 ```==,!=,===,!==,<=,>=,<,>``` 这些比较运算符:
74+
75+
```elixir
6776
iex> 1 == 1
6877
true
6978
iex> 1 != 2
@@ -72,16 +81,17 @@ iex> 1 < 2
7281
true
7382
```
7483

75-
==和===的不同之处是后者在判断数字时更严格:
76-
```
84+
其中```==``````===```的不同之处是后者在判断数字时更严格:
85+
86+
```elixir
7787
iex> 1 == 1.0
7888
true
7989
iex> 1 === 1.0
8090
false
8191
```
8292

8393
在Elixir中,可以判断不同类型数据的大小:
84-
```
94+
```elixir
8595
iex> 1 < :atom
8696
true
8797
```
@@ -90,5 +100,4 @@ true
90100
```
91101
number < atom < reference < functions < port < pid < tuple < maps < list < bitstring
92102
```
93-
不用背,只要知道有这么回事儿就可以。
94-
103+
不用强记,只要知道有这么回事儿就可以。

4-pattern-matching.md

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,24 @@
11
4-模式匹配
22
==========
3-
[匹配运算符](#41-%E5%8C%B9%E9%85%8D%E8%BF%90%E7%AE%97%E7%AC%A6)
4-
[模式匹配](#42-%E6%A8%A1%E5%BC%8F%E5%8C%B9%E9%85%8D)
5-
[pin运算符](#43-pin%E8%BF%90%E7%AE%97%E7%AC%A6)
63

74
本章起教程进入 _不那么基础的_ 阶段,开始涉及函数式编程概念。
8-
在Elixir中,```=```运算符实际上是一个匹配运算符。
9-
本章将讲解如何使用=运算符来对数据结构进行模式匹配。
10-
最后本章还会讲解pin运算符(^),用来访问某变量之前绑定的值。
5+
对之前没有函数式编程经验的人来说,这一章是一个基础,需要好好学习和理解。
6+
7+
在Elixir中,```=```运算符实际上叫做 *匹配运算符*
8+
本章将讲解如何使用```=```运算符来对各种数据结构进行模式匹配。
9+
最后本章还会讲解pin运算符(```^```),用来访问某变量之前绑定的值。
1110

1211
## 4.1-匹配运算符
12+
1313
我们已经多次使用```=```符号进行变量的赋值操作:
1414
```elixir
1515
iex> x = 1
1616
1
1717
iex> x
1818
1
1919
```
20-
在Elixir中,```=```号其实称为匹配运算符。下面来学习这样的概念:
20+
21+
在Elixir中,```=```作为 *匹配运算符*。下面来学习这样的概念:
2122
```elixir
2223
iex> 1 = x
2324
1
@@ -26,18 +27,21 @@ iex> 2 = x
2627
```
2728

2829
注意```1 = x```是一个合法的表达式。
29-
由于前面给x赋值为1,左右相同,所以它匹配成功了。而两侧不匹配的时候,MatchError将被抛出。
30+
由于前面的例子给x赋值为1,因此在匹配时左右相同,所以它匹配成功了。而两侧不匹配的时候,MatchError将被抛出。
3031

3132
变量只有在匹配操作符```=```的左侧时才被赋值:
3233
```elixir
3334
iex> 1 = unknown
3435
** (RuntimeError) undefined function: unknown/0
3536
```
36-
错误原因是unknown变量没有被赋过值,Elixir猜你想调用一个名叫unknown/0的函数
37+
错误原因是unknown变量没有被赋过值,Elixir猜你想调用一个名叫```unknown/0```的函数
3738
但是找不到这样的函数。
3839

40+
>
41+
变量名在等号左边,Elixir认为是赋值表达式;变量名放在右边,Elixir认为是拿该变量的值和左边的值做匹配。
42+
3943
## 4.2-模式匹配
40-
匹配运算符不光可以匹配简单数值,还能用来解构复杂的数据类型。例如,我们在元组上使用模式匹配:
44+
匹配运算符不光可以匹配简单数值,还能用来 *解构* 复杂的数据类型。例如,我们在元组上使用模式匹配:
4145
```elixir
4246
iex> {a, b, c} = {:hello, "world", 42}
4347
{:hello, "world", 42}
@@ -46,20 +50,22 @@ iex> a
4650
iex> b
4751
"world"
4852
```
49-
在两端不匹配的情况下,模式匹配会失败。比方说,匹配两端的元组不一样长:
53+
54+
在两端不匹配的情况下,模式匹配会失败。比方说,匹配的两端的元组不一样长:
5055
```elixir
5156
iex> {a, b, c} = {:hello, "world"}
5257
** (MatchError) no match of right hand side value: {:hello, "world"}
5358
```
5459

55-
或者两端不是一个类型
60+
或者两端模式有区别(比如两端数据类型不同)
5661
```elixir
5762
iex> {a, b, c} = [:hello, "world", "!"]
5863
** (MatchError) no match of right hand side value: [:hello, "world", "!"]
5964
```
6065

61-
有趣的是,我们可以匹配特定值。
62-
下面例子中匹配的左端当且仅当右端是个元组,且第一个元素是原子```:ok```
66+
利用“匹配”的这个概念,我们可以匹配特定值,或者在匹配成功时。
67+
68+
下面例子中先写好了匹配的左端,它要求右端必须是个元组,且第一个元素是原子```:ok```
6369
```elixir
6470
iex> {:ok, result} = {:ok, 13}
6571
{:ok, 13}
@@ -72,7 +78,7 @@ iex> {:ok, result} = {:error, :oops}
7278

7379
用在列表上:
7480
```elixir
75-
iex> [a, b, c] = [1, 2, 3]
81+
iex> [a, 2, 3] = [1, 2, 3]
7682
[1, 2, 3]
7783
iex> a
7884
1
@@ -95,7 +101,8 @@ iex> [h|t] = []
95101
** (MatchError) no match of right hand side value: []
96102
```
97103

98-
>[head|tail]这种形式不光在模式匹配时可以用,还可以用作向列表插入前置数值:
104+
>
105+
[head|tail]这种形式不光在模式匹配时可以用,还可以用作向列表插入前置数值:
99106
```elixir
100107
iex> list = [1, 2, 3]
101108
[1, 2, 3]
@@ -106,6 +113,13 @@ iex> [0|list]
106113
模式匹配使得程序员可以容易地解构数据结构(如元组和列表)。
107114
在后面我们还会看到,它是Elixir的一个基础,对其它数据结构同样适用,比如图和二进制。
108115

116+
小结:
117+
* 模式匹配使用```=```符号
118+
* 匹配中等号左右的“模式”必须相同
119+
* 变量在等号左侧才会被赋值
120+
* 变量在右侧时必须有值,Elixir拿这个值和左侧相应位置的元素做匹配
121+
122+
109123
## 4.3-pin运算符
110124
在Elixir中,变量可以被重新绑定:
111125
```elixir

0 commit comments

Comments
 (0)