Skip to content

Commit dd8abc4

Browse files
committed
更新20,21,易读通顺
1 parent 128dd1d commit dd8abc4

File tree

2 files changed

+37
-27
lines changed

2 files changed

+37
-27
lines changed

20-typespecs-behaviors.md

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,28 @@
66
Elixir是一门动态类型语言,Elixir中所有数据类型都是在运行时动态推定的。
77
然而,Elixir还提供了 **typespecs** 标记,用来:
88

9-
1. 声明自定义数据类型
10-
2. 声明含有显式类型说明的函数签名(即函数的规格说明)
9+
1. 声明自定义数据类型
10+
2. 声明含有显式类型说明的函数签名(即函数的规格说明)
1111

1212
### 函数的规格说明(spec)
1313

14-
默认地,Elixir提供了一些基础数据类型,比如 `integer` 或者 `pid`还有其它一些复杂的:
15-
如函数`round/1`,它对一个float类型的数值四舍五入。
14+
默认地,Elixir提供了一些基础数据类型,表示为 `integer` 或者 `pid`
15+
还有一些复杂情形:如函数`round/1`为例,它对一个float类型的数值四舍五入。
1616
它以一个`number`(一个`integer``float`)作为参数,返回一个`integer`
1717

18-
[round函数的文档](http://elixir-lang.org/docs/stable/elixir/Kernel.html#round/1)
19-
里面描述`round/1`的函数签名为
18+
那么,它在[round函数的文档](http://elixir-lang.org/docs/stable/elixir/Kernel.html#round/1)
19+
里面记载的函数签名为
2020

2121
```
2222
round(number) :: integer
2323
```
2424

25-
`::` 表示其左边的函数 *返回* 一个其右面声明的类型的值。
26-
函数的规格说明写在函数定义的前面、以`@spec`指令打头。
27-
比如`round/1`函数可以这么写:
25+
`::` 表示其左边的函数 *返回* 一个其右面声明的类型的值。函数名后面括号中是参数类型的列表。
26+
27+
如果想特别注明某个函数的参数类型及返回值类型,那么可以在定义函数的时候,
28+
在函数前面使用`@spec`指令附加上函数的规格说明(spec)。
29+
30+
比如,在函数库源码中,函数`round/1`是这么写的:
2831

2932
```elixir
3033
@spec round(number) :: integer
@@ -33,32 +36,34 @@ def round(number), do: # 具体实现 ...
3336

3437
Elixir还支持组合类型。例如,整数的列表,它的类型表示为`[integer]`
3538
可以阅读[typespecs的文档](http://elixir-lang.org/docs/stable/elixir/typespecs.html)
36-
查看Elixir提供的所有内建类型
39+
查看Elixir提供的所有内建类型的表示方法
3740

3841
### 定义自定义类型
3942

40-
Elixir提供了许多有用的内建类型,而且也很方便去创建自定义类型应用于合适的场景
41-
在定义模块的时候,通过加上`@type`指令就可以实现
43+
Elixir提供了许多有用的内建类型,而且也方便创建自定义类型应用于特定场景
44+
方法是在定义的时候,加上`@type`指令
4245

43-
比方我们有个模块叫做`LuosyCalculator`,可以执行常见的算术计算(如求和、计算乘积等)。
44-
但是,它不是返回数值,而是返回一个元祖,该元祖第一个元素是计算结果,第二个是随机的文字记号。
46+
比如我们有个模块叫做`LuosyCalculator`,可以执行常见的算术计算(如求和、计算乘积等)。
47+
但是,它的函数不是返回结果数值,而是返回一个元祖,
48+
该元祖第一个元素是计算结果,第二个是随机的文字记号。
4549

4650
```elixir
4751
defmodule LousyCalculator do
4852
@spec add(number, number) :: {number, String.t}
49-
def add(x, y), do: {x + y, "你用计算器算这个?!"}
53+
def add(x, y), do: { x + y, "你用计算器算这个?!" }
5054

5155
@spec multiply(number, number) :: {number, String.t}
52-
def multiply(x, y), do: {x * y, "老天,不是吧?!"}
56+
def multiply(x, y), do: { x * y, "老天,不是吧?!" }
5357
end
5458
```
5559

5660
从例子中可以看出,元组是复合类型。每个元组都定义了其具体元素类型。
57-
至于为何是`String.t`而不是`string`,可以参考
58-
[这篇文章](http://elixir-lang.org/docs/stable/elixir/typespecs.html#Notes)
61+
至于为何是`String.t`而不是`string`的原因,可以参考
62+
[这篇文章](http://elixir-lang.org/docs/stable/elixir/typespecs.html#Notes)
63+
此处不多说明。
5964

6065
像这样定义函数规格说明是没问题,但是一次次重复写这种复合类型的
61-
样式名称`{number, String.t}`很快会厌烦
66+
表示方法`{number, String.t}`很快会厌烦的吧
6267
我们可以使用`@type`指令来声明我们自定义的类型:
6368

6469
```elixir
@@ -76,9 +81,9 @@ defmodule LousyCalculator do
7681
end
7782
```
7883

79-
指令`@typedoc`,和`@doc``@moduledoc`指令类似,被用来记录自定义类型
84+
指令`@typedoc`,和`@doc``@moduledoc`指令类似,用来解释说明自定义的类型,放在`@type`前面
8085

81-
自定义类型通过`@type`定义,可以从其定义的模块导出并被外界访问
86+
另外,通过`@type`定义的自定义类型,实际上也是模块的成员,可以被外界访问
8287

8388
```elixir
8489
defmodule QuietCalculator do
@@ -94,9 +99,9 @@ end
9499

95100
### 静态代码分析
96101

97-
Typespecs的作用不仅仅是被用来作为程序文档说明。举个例子,
102+
给函数等元素标记类型或者签名的作用,不仅仅是被用来作为程序文档说明。举个例子,
98103
Erlang工具[Dialyzer][Dialyzer](http://www.erlang.org/doc/man/dialyzer.html)
99-
使用typespecs来进行代码静态分析
104+
通过这些类型或者签名标记,进行代码静态分析
100105
这就是为什么我们在 `QuiteCalculator` 例子中,
101106
即使 `make_quite/1` 是个私有函数,也写了函数规格说明。
102107

21-erlang-lib.md

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
11
21-Erlang库
22
============
33

4-
Elixir对Erlang库提供了完善的交互。实际上,Elixir不是简单地去对Erlang库进行语言包装,
5-
而是直接连接Erlang的代码(因为同源,Elixir以特定语法来直接调用Erlang库函数)。
4+
正如前文所言,Elixir是基于Erlang实现的编程语言。
5+
对于Erlang语言库,Elixir提供了完善的交互能力。
6+
而且,实际上,Elixir不只是简单地对Erlang库功能进行语言上的包装(是的,没有Elixir版本的对应Erlang库函数),
7+
而是直接连接Erlang代码(因为同源,Elixir以特定语法来直接调用Erlang库函数)。
68
本章将展示一些Elixir中没有,但是常用(常见+有用)的Erlang功能函数。
79

810
>随着对Elixir更加深入的学习和使用,你可能会更多地阅读参考Erlang的
911
[标准库手册](http://erlang.org/doc/apps/stdlib/index.html)
1012

1113
## 二进制串模块
1214

13-
内建的Elixir字符串模块处理UTF-8编码过的二进制串(binaries)。而Erlang的
14-
[二进制串模块](http://erlang.org/doc/man/binary.html)可能对你更加有用,
15+
内建的Elixir字符串模块用来处理UTF-8编码过的二进制串(binaries)。
16+
而Erlang的[二进制串模块](http://erlang.org/doc/man/binary.html)可能对你更加有用,
1517
因为它可以处理的二进制串不一定非要是UTF-8编码的:
1618

1719
```iex
@@ -24,6 +26,9 @@ iex> :binary.bin_to_list "Ø"
2426
从上面的例子你就能看出一些区别来了;`String`模块返回UTF-8的字符码,
2527
`:binary`是原始的数据字节。
2628

29+
>Elixir引用Erlang的库函数十分简单。正如这个例子所示,在Erlang库模块名称前面加上冒号,
30+
就可以直接调用Erlang的库函数了。
31+
2732
## 格式化的字符串输出
2833

2934
Elixir中并没有类似于C中的`printf`函数。作为一个可选项,你可以使用字符串插值来完成同样的功能:

0 commit comments

Comments
 (0)