11% ジェネリクス
22<!-- % Generics -->
33
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> ` はジェネリックです。
1419
1520``` rust
1621enum Option <T > {
@@ -19,43 +24,53 @@ enum Option<T> {
1924}
2025```
2126
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> ` の使用例が以下になります。
2734
2835``` rust
2936let x : Option <i32 > = Some (5 );
3037```
3138
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+ 型が不一致であれば、以下のようなエラーが発生します。
3850
3951``` rust,ignore
4052let x: Option<f64> = Some(5);
4153// error: mismatched types: expected `core::option::Option<f64>`,
4254// found `core::option::Option<_>` (expected f64 but found integral variable)
4355```
4456
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+ リテラルと宣言の型をぴったり合わせなければなりません。
4861
4962``` rust
5063let x : Option <i32 > = Some (5 );
5164let y : Option <f64 > = Some (5.0f64 );
5265```
5366
5467<!-- This is just fine. One definition, multiple uses. -->
55- これだけで結構です。1つの定義で、多くの用途が得られます。
68+ これだけで結構です。
69+ 1つの定義で、多くの用途が得られます。
5670
5771<!-- 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> ` について考えてみます。
5974
6075``` rust
6176enum Result <T , E > {
@@ -64,9 +79,11 @@ enum Result<T, E> {
6479}
6580```
6681
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> ` を、
7087
7188``` rust
7289enum Result <A , Z > {
@@ -75,12 +92,13 @@ enum Result<A, Z> {
7592}
7693```
7794
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は気にしません。
8199
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. -->
84102` Result<T, E> ` 型は計算の結果を返すために使われることが想定されており、正常に動作しなかった場合にエラーの値を返す機能を持っています。
85103
86104<!-- ## Generic functions -->
@@ -96,9 +114,10 @@ fn takes_anything<T>(x: T) {
96114}
97115```
98116
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 ` 型である」という意味です。
102121
103122<!-- Multiple arguments can have the same generic type: -->
104123複数の引数が同じジェネリックな型を持つこともできます。
@@ -134,12 +153,12 @@ let int_origin = Point { x: 0, y: 0 };
134153let float_origin = Point { x : 0.0 , y : 0.0 };
135154```
136155
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. -->
139158関数と同様に、 ` <T> ` がジェネリックパラメータを宣言する場所であり、型宣言において ` x: T ` を使うのも同じです。
140159
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`: -->
143162ジェネリックな ` struct ` に実装を追加したい場合、 ` impl ` の後に型パラメータを宣言するだけです。
144163
145164``` rust
@@ -155,12 +174,16 @@ impl<T> Point<T> {
155174}
156175```
157176
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 ] を読んで下さい。
164187
165188[ traits ] : traits.html
166189[ Vec ] : ../std/vec/struct.Vec.html
0 commit comments