|
1 | 1 | 20-Typespecs和behaviors
|
2 | 2 | =======================
|
3 | 3 |
|
4 |
| -## Types and specs |
| 4 | +## 类型(type)和规格说明(spec) |
5 | 5 |
|
6 |
| -Elixir是一门动态类型语言,Elixir中所有类型都是在运行时动态推定的。 |
7 |
| -然而,Elixir还是提供了 **typespecs** 标记,用来: |
8 |
| -1. 声明自定义数据类型 |
9 |
| -2. 声明含有类型的函数签名(即函数的规格说明) |
| 6 | +Elixir是一门动态类型语言,Elixir中所有数据类型都是在运行时动态推定的。 |
| 7 | +然而,Elixir还提供了 **typespecs** 标记,用来: |
10 | 8 |
|
11 |
| -### 函数的规格说明 |
| 9 | + 1. 声明自定义数据类型 |
| 10 | + 2. 声明含有显式类型说明的函数签名(即函数的规格说明) |
| 11 | + |
| 12 | +### 函数的规格说明(spec) |
| 13 | + |
| 14 | +默认地,Elixir提供了一些基础数据类型,比如 `integer` 或者 `pid`。还有其它一些复杂的: |
| 15 | +如函数`round/1`,它对一个float类型的数值四舍五入。 |
| 16 | +它以一个`number`(一个`integer`或`float`)作为参数,返回一个`integer`。 |
| 17 | + |
| 18 | +[round函数的文档](http://elixir-lang.org/docs/stable/elixir/Kernel.html#round/1) |
| 19 | +里面描述`round/1`的函数签名为: |
12 | 20 |
|
13 |
| -默认地,Elixir提供了一些基础类型,比如`integer`或者`pid`,还有其它一些复杂的: |
14 |
| -如`round/1`函数,它对一个float类型四舍五入。它以一个`number`作为参数 |
15 |
| -(一个`integer`或`float`),返回一个`integer`。 |
16 |
| -你可以阅读[这篇文档](http://elixir-lang.org/docs/stable/elixir/Kernel.html#round/1), |
17 |
| -`round/1`含有类型的签名为: |
18 | 21 | ```
|
19 | 22 | round(number) :: integer
|
20 | 23 | ```
|
21 | 24 |
|
22 |
| -`::` means that the function on the left side *returns* a value whose type is what's on the right side. Function specs are written with the `@spec` directive, placed right before the function definition. The `round/1` function could be written as: |
| 25 | +`::` 表示其左边的函数 *返回* 一个其右面声明的类型的值。 |
| 26 | +函数的规格说明写在函数定义的前面、以`@spec`指令打头。 |
| 27 | +比如`round/1`函数可以这么写: |
23 | 28 |
|
24 | 29 | ```elixir
|
25 | 30 | @spec round(number) :: integer
|
26 |
| -def round(number), do: # implementation... |
| 31 | +def round(number), do: # 具体实现 ... |
27 | 32 | ```
|
28 | 33 |
|
29 |
| -Elixir supports compound types as well. For example, a list of integers has type `[integer]`. You can see all the built-in types provided by Elixir [in the typespecs docs](/docs/stable/elixir/typespecs.html). |
| 34 | +Elixir还支持组合类型。例如,整数的列表,它的类型表示为`[integer]`。 |
| 35 | +可以阅读[typespecs的文档](http://elixir-lang.org/docs/stable/elixir/typespecs.html) |
| 36 | +查看Elixir提供的所有内建类型。 |
30 | 37 |
|
31 |
| -### Defining custom types |
| 38 | +### 定义自定义类型 |
32 | 39 |
|
33 |
| -While Elixir provides a lot of useful built-in types, it's convenient to define custom types when appropriate. This can be done when defining modules through the `@type` directive. |
| 40 | +Elixir提供了许多有用的内建类型,而且也很方便去创建自定义类型应用于合适的场景。 |
| 41 | +在定义模块的时候,通过加上`@type`指令就可以实现。 |
34 | 42 |
|
35 |
| -Say we have a `LousyCalculator` module, which performs the usual arithmetic operations (sum, product and so on) but, instead of returning numbers, it returns tuples with the result of an operation as the first element and a random remark as the second element. |
| 43 | +比方我们有个模块叫做`LuosyCalculator`,可以执行常见的算术计算(如求和、计算乘积等)。 |
| 44 | +但是,它不是返回数值,而是返回一个元祖,该元祖第一个元素是计算结果,第二个是随机的文字记号。 |
36 | 45 |
|
37 | 46 | ```elixir
|
38 | 47 | defmodule LousyCalculator do
|
39 | 48 | @spec add(number, number) :: {number, String.t}
|
40 |
| - def add(x, y), do: {x + y, "You need a calculator to do that?!"} |
| 49 | + def add(x, y), do: {x + y, "你用计算器算这个?!"} |
41 | 50 |
|
42 | 51 | @spec multiply(number, number) :: {number, String.t}
|
43 |
| - def multiply(x, y), do: {x * y, "Jeez, come on!"} |
| 52 | + def multiply(x, y), do: {x * y, "老天,不是吧?!"} |
44 | 53 | end
|
45 | 54 | ```
|
46 | 55 |
|
47 |
| -As you can see in the example, tuples are a compound type and each tuple is identified by the types inside it. To understand why `String.t` is not written as `string`, have another look at the [notes in the typespecs docs](/docs/stable/elixir/typespecs.html#Notes). |
| 56 | +从例子中可以看出,元祖是复合类型。每个元祖都定义了其具体元素类型。 |
| 57 | +至于为何是`String.t`而不是`string`,可以参考 |
| 58 | +[这篇文章](http://elixir-lang.org/docs/stable/elixir/typespecs.html#Notes)。 |
48 | 59 |
|
49 | 60 | Defining function specs this way works, but it quickly becomes annoying since we're repeating the type `{number, String.t}` over and over. We can use the `@type` directive in order to declare our own custom type.
|
50 | 61 |
|
@@ -131,4 +142,5 @@ defmodule YAMLParser do
|
131 | 142 | end
|
132 | 143 | ```
|
133 | 144 |
|
| 145 | + |
134 | 146 | If a module adopting a given behaviour doesn't implement one of the callbacks required by that behaviour, a compile-time warning will be generated.
|
0 commit comments