1
1
% ジェネリクス
2
2
<!-- % Generics -->
3
3
4
- <!-- Sometimes, when writing a function or data type, we may want it to work for
5
- multiple types of arguments. In Rust, we can do this with generics.
6
- Generics are called ‘parametric polymorphism’ in type theory,
7
- which means that they are types or functions that have multiple forms (‘poly’
8
- is multiple, ‘morph’ is form) over a given parameter (‘parametric’). -->
9
- 時々、関数やデータ型を書いていると、引数が複数の型に対応したものが欲しくなることもあります。Rustでは、ジェネリクスを用いてこれを実現しています。ジェネリクスは型理論において「パラメトリック多相」(parametric polymorphism)と呼ばれ、与えられたパラメータにより(「parametric」)型もしくは関数が多数の様相(「poly」は多様、「morph」は様相を意味します)(訳注: ここで「様相」は型を指します)を持つことを意味しています。
10
-
11
- <!-- Anyway, enough type theory, let’s check out some generic code. Rust’s
12
- standard library provides a type, `Option<T>`, that’s generic: -->
13
- さて、型理論はもう十分です。続いてジェネリックなコードを幾つか見ていきましょう。Rustが標準ライブラリで提供している型 ` Option<T> ` はジェネリックです。
4
+ <!-- Sometimes, when writing a function or data type, we may want it to work for -->
5
+ <!-- multiple types of arguments. In Rust, we can do this with generics. -->
6
+ <!-- Generics are called ‘parametric polymorphism’ in type theory, -->
7
+ <!-- which means that they are types or functions that have multiple forms (‘poly’ -->
8
+ <!-- is multiple, ‘morph’ is form) over a given parameter (‘parametric’). -->
9
+ 時々、関数やデータ型を書いていると、引数が複数の型に対応したものが欲しくなることもあります。
10
+ Rustでは、ジェネリクスを用いてこれを実現しています。
11
+ ジェネリクスは型理論において「パラメトリック多相」(parametric polymorphism)と呼ばれ、与えられたパラメータにより(「parametric」)型もしくは関数が多数の様相(「poly」は多様、「morph」は様相を意味します)
12
+ (訳注: ここで「様相」は型を指します)を持つことを意味しています。
13
+
14
+ <!-- Anyway, enough type theory, let’s check out some generic code. Rust’s -->
15
+ <!-- standard library provides a type, `Option<T>`, that’s generic: -->
16
+ さて、型理論はもう十分です。
17
+ 続いてジェネリックなコードを幾つか見ていきましょう。
18
+ Rustが標準ライブラリで提供している型 ` Option<T> ` はジェネリックです。
14
19
15
20
``` rust
16
21
enum Option <T > {
@@ -19,43 +24,53 @@ enum Option<T> {
19
24
}
20
25
```
21
26
22
- <!-- The `<T>` part, which you’ve seen a few times before, indicates that this is
23
- a generic data type. Inside the declaration of our `enum`, wherever we see a `T`,
24
- we substitute that type for the same type used in the generic. Here’s an
25
- example of using `Option<T>`, with some extra type annotations: -->
26
- ` <T> ` の部分は、前に少し見たことがあると思いますが、これがジェネリックなデータ型であることを示しています。 ` enum ` の宣言内であれば、どこでも ` T ` を使うことができ、宣言内に登場する同じ型をジェネリック内で ` T ` 型に置き換えています。型注釈を用いた` Option<T> ` の使用例が以下になります。
27
+ <!-- The `<T>` part, which you’ve seen a few times before, indicates that this is -->
28
+ <!-- a generic data type. Inside the declaration of our `enum`, wherever we see a `T`, -->
29
+ <!-- we substitute that type for the same type used in the generic. Here’s an -->
30
+ <!-- example of using `Option<T>`, with some extra type annotations: -->
31
+ ` <T> ` の部分は、前に少し見たことがあると思いますが、これがジェネリックなデータ型であることを示しています。
32
+ ` enum ` の宣言内であれば、どこでも ` T ` を使うことができ、宣言内に登場する同じ型をジェネリック内で ` T ` 型に置き換えています。
33
+ 型注釈を用いた` Option<T> ` の使用例が以下になります。
27
34
28
35
``` rust
29
36
let x : Option <i32 > = Some (5 );
30
37
```
31
38
32
- <!-- In the type declaration, we say `Option<i32>`. Note how similar this looks to
33
- `Option<T>`. So, in this particular `Option`, `T` has the value of `i32`. On
34
- the right-hand side of the binding, we make a `Some(T)`, where `T` is `5`.
35
- Since that’s an `i32`, the two sides match, and Rust is happy. If they didn’t
36
- match, we’d get an error: -->
37
- この型宣言では ` Option<i32> ` と書かれています。 ` Option<T> ` の違いに注目して下さい。そう、上記の ` Option ` では ` T ` の値は ` i32 ` です。この束縛の右辺の ` Some(T) ` では、 ` T ` は ` 5 ` となります。それが ` i32 ` なので、両辺の型が一致するため、Rustは満足します。型が不一致であれば、以下のようなエラーが発生します。
39
+ <!-- In the type declaration, we say `Option<i32>`. Note how similar this looks to -->
40
+ <!-- `Option<T>`. So, in this particular `Option`, `T` has the value of `i32`. On -->
41
+ <!-- the right-hand side of the binding, we make a `Some(T)`, where `T` is `5`. -->
42
+ <!-- Since that’s an `i32`, the two sides match, and Rust is happy. If they didn’t -->
43
+ <!-- match, we’d get an error: -->
44
+ この型宣言では ` Option<i32> ` と書かれています。
45
+ ` Option<T> ` の違いに注目して下さい。
46
+ そう、上記の ` Option ` では ` T ` の値は ` i32 ` です。
47
+ この束縛の右辺の ` Some(T) ` では、 ` T ` は ` 5 ` となります。
48
+ それが ` i32 ` なので、両辺の型が一致するため、Rustは満足します。
49
+ 型が不一致であれば、以下のようなエラーが発生します。
38
50
39
51
``` rust,ignore
40
52
let x: Option<f64> = Some(5);
41
53
// error: mismatched types: expected `core::option::Option<f64>`,
42
54
// found `core::option::Option<_>` (expected f64 but found integral variable)
43
55
```
44
56
45
- <!-- That doesn’t mean we can’t make `Option<T>`s that hold an `f64`! They just have
46
- to match up: -->
47
- これは ` f64 ` を保持する ` Option<T> ` が作れないという意味ではありませんからね!リテラルと宣言の型をぴったり合わせなければなりません。
57
+ <!-- That doesn’t mean we can’t make `Option<T>`s that hold an `f64`! They just have -->
58
+ <!-- to match up: -->
59
+ これは ` f64 ` を保持する ` Option<T> ` が作れないという意味ではありませんからね!
60
+ リテラルと宣言の型をぴったり合わせなければなりません。
48
61
49
62
``` rust
50
63
let x : Option <i32 > = Some (5 );
51
64
let y : Option <f64 > = Some (5.0f64 );
52
65
```
53
66
54
67
<!-- This is just fine. One definition, multiple uses. -->
55
- これだけで結構です。1つの定義で、多くの用途が得られます。
68
+ これだけで結構です。
69
+ 1つの定義で、多くの用途が得られます。
56
70
57
71
<!-- Generics don’t have to only be generic over one type. Consider another type from Rust’s standard library that’s similar, `Result<T, E>`: -->
58
- ジェネリクスにおいてジェネリックな型は1つまで、といった制限はありません。Rustの標準ライブラリに入っている類似の型 ` Result<T, E> ` について考えてみます。
72
+ ジェネリクスにおいてジェネリックな型は1つまで、といった制限はありません。
73
+ Rustの標準ライブラリに入っている類似の型 ` Result<T, E> ` について考えてみます。
59
74
60
75
``` rust
61
76
enum Result <T , E > {
@@ -64,9 +79,11 @@ enum Result<T, E> {
64
79
}
65
80
```
66
81
67
- <!-- This type is generic over _two_ types: `T` and `E`. By the way, the capital letters
68
- can be any letter you’d like. We could define `Result<T, E>` as: -->
69
- この型では ` T ` と ` E ` の _ 2つ_ がジェネリックです。ちなみに、大文字の部分はあなたの好きな文字で構いません。もしあなたが望むなら ` Result<T, E> ` を、
82
+ <!-- This type is generic over _two_ types: `T` and `E`. By the way, the capital letters -->
83
+ <!-- can be any letter you’d like. We could define `Result<T, E>` as: -->
84
+ この型では ` T ` と ` E ` の _ 2つ_ がジェネリックです。
85
+ ちなみに、大文字の部分はあなたの好きな文字で構いません。
86
+ もしあなたが望むなら ` Result<T, E> ` を、
70
87
71
88
``` rust
72
89
enum Result <A , Z > {
@@ -75,12 +92,13 @@ enum Result<A, Z> {
75
92
}
76
93
```
77
94
78
- <!-- if we wanted to. Convention says that the first generic parameter should be
79
- `T`, for ‘type’, and that we use `E` for ‘error’. Rust doesn’t care, however. -->
80
- のように定義できます。慣習としては、「Type」から第1ジェネリックパラメータは ` T ` であるべきですし、「Error」から ` E ` を用いるのですが、Rustは気にしません。
95
+ <!-- if we wanted to. Convention says that the first generic parameter should be -->
96
+ <!-- `T`, for ‘type’, and that we use `E` for ‘error’. Rust doesn’t care, however. -->
97
+ のように定義できます。
98
+ 慣習としては、「Type」から第1ジェネリックパラメータは ` T ` であるべきですし、「Error」から ` E ` を用いるのですが、Rustは気にしません。
81
99
82
- <!-- The `Result<T, E>` type is intended to be used to return the result of a
83
- computation, and to have the ability to return an error if it didn’t work out. -->
100
+ <!-- The `Result<T, E>` type is intended to be used to return the result of a -->
101
+ <!-- computation, and to have the ability to return an error if it didn’t work out. -->
84
102
` Result<T, E> ` 型は計算の結果を返すために使われることが想定されており、正常に動作しなかった場合にエラーの値を返す機能を持っています。
85
103
86
104
<!-- ## Generic functions -->
@@ -96,9 +114,10 @@ fn takes_anything<T>(x: T) {
96
114
}
97
115
```
98
116
99
- <!-- The syntax has two parts: the `<T>` says “this function is generic over one
100
- type, `T`”, and the `x: T` says “x has the type `T`.” -->
101
- 構文は2つのパーツから成ります。 ` <T> ` は「この関数は1つの型、 ` T ` に対してジェネリックである」ということであり、 ` x: T ` は「xは ` T ` 型である」という意味です。
117
+ <!-- The syntax has two parts: the `<T>` says “this function is generic over one -->
118
+ <!-- type, `T`”, and the `x: T` says “x has the type `T`.” -->
119
+ 構文は2つのパーツから成ります。
120
+ ` <T> ` は「この関数は1つの型、 ` T ` に対してジェネリックである」ということであり、 ` x: T ` は「xは ` T ` 型である」という意味です。
102
121
103
122
<!-- Multiple arguments can have the same generic type: -->
104
123
複数の引数が同じジェネリックな型を持つこともできます。
@@ -134,12 +153,12 @@ let int_origin = Point { x: 0, y: 0 };
134
153
let float_origin = Point { x : 0.0 , y : 0.0 };
135
154
```
136
155
137
- <!-- Similar to functions, the `<T>` is where we declare the generic parameters,
138
- and we then use `x: T` in the type declaration, too. -->
156
+ <!-- Similar to functions, the `<T>` is where we declare the generic parameters, -->
157
+ <!-- and we then use `x: T` in the type declaration, too. -->
139
158
関数と同様に、 ` <T> ` がジェネリックパラメータを宣言する場所であり、型宣言において ` x: T ` を使うのも同じです。
140
159
141
- <!-- When you want to add an implementation for the generic `struct`, you just
142
- declare the type parameter after the `impl`: -->
160
+ <!-- When you want to add an implementation for the generic `struct`, you just -->
161
+ <!-- declare the type parameter after the `impl`: -->
143
162
ジェネリックな ` struct ` に実装を追加したい場合、 ` impl ` の後に型パラメータを宣言するだけです。
144
163
145
164
``` rust
@@ -155,12 +174,16 @@ impl<T> Point<T> {
155
174
}
156
175
```
157
176
158
- <!-- So far you’ve seen generics that take absolutely any type. These are useful in
159
- many cases: you’ve already seen `Option<T>`, and later you’ll meet universal
160
- container types like [`Vec<T>`][Vec]. On the other hand, often you want to
161
- trade that flexibility for increased expressive power. Read about [trait
162
- bounds][traits] to see why and how. -->
163
- ここまででありとあらゆる型をとることのできるジェネリクスについて見てきました。多くの場合これらは有用です。 ` Option<T> ` は既に見た通りですし、のちに ` Vec<T> ` のような普遍的なコンテナ型を知ることになるでしょう。一方で、その柔軟性と引き換えに表現力を増加させたくなることもあります。それは何故か、そしてその方法を知るためには [ トレイト境界] [ traits ] を読んで下さい。
177
+ <!-- So far you’ve seen generics that take absolutely any type. These are useful in -->
178
+ <!-- many cases: you’ve already seen `Option<T>`, and later you’ll meet universal -->
179
+ <!-- container types like [`Vec<T>`][Vec]. On the other hand, often you want to -->
180
+ <!-- trade that flexibility for increased expressive power. Read about [trait -->
181
+ <!-- bounds][traits] to see why and how. -->
182
+ ここまででありとあらゆる型をとることのできるジェネリクスについて見てきました。
183
+ 多くの場合これらは有用です。
184
+ ` Option<T> ` は既に見た通りですし、のちに ` Vec<T> ` のような普遍的なコンテナ型を知ることになるでしょう。
185
+ 一方で、その柔軟性と引き換えに表現力を増加させたくなることもあります。
186
+ それは何故か、そしてその方法を知るためには [ トレイト境界] [ traits ] を読んで下さい。
164
187
165
188
[ traits ] : traits.html
166
189
[ Vec ] : ../std/vec/struct.Vec.html
0 commit comments