-
Notifications
You must be signed in to change notification settings - Fork 72
4.18. Generics #38
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
4.18. Generics #38
Changes from 8 commits
58d3b11
d548b1e
5d44590
92f847e
53fc045
335e85d
5e66d42
90bc9ad
e795758
cba2886
24d38b5
00971f5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,16 @@ | ||
% Generics | ||
% ジェネリクス | ||
<!-- % Generics --> | ||
|
||
Sometimes, when writing a function or data type, we may want it to work for | ||
<!-- Sometimes, when writing a function or data type, we may want it to work for | ||
multiple types of arguments. In Rust, we can do this with generics. | ||
Generics are called ‘parametric polymorphism’ in type theory, | ||
which means that they are types or functions that have multiple forms (‘poly’ | ||
is multiple, ‘morph’ is form) over a given parameter (‘parametric’). | ||
is multiple, ‘morph’ is form) over a given parameter (‘parametric’). --> | ||
時々、関数やデータ型を書いていると、引数が複数の型に対応したものが欲しくなることもあります。Rustでは、ジェネリクスを用いてこれを実現しています。ジェネリクスは型理論において「パラメトリック多相」(parametric polymorphism)と呼ばれ、与えられたパラメータにより(「parametric」)型もしくは関数が多数の様相(「poly」は多様、「morph」は様相を意味します)(訳注: ここで「様相」は型を指します)を持つことを意味しています。 | ||
|
||
Anyway, enough type theory, let’s check out some generic code. Rust’s | ||
standard library provides a type, `Option<T>`, that’s generic: | ||
<!-- Anyway, enough type theory, let’s check out some generic code. Rust’s | ||
standard library provides a type, `Option<T>`, that’s generic: --> | ||
さて、型理論はこれで十分です。続いてジェネリックなコードを幾つか見ていきましょう。Rustが標準ライブラリで提供している型 `Option<T>` はジェネリックです。 | ||
|
||
```rust | ||
enum Option<T> { | ||
|
@@ -16,38 +19,43 @@ enum Option<T> { | |
} | ||
``` | ||
|
||
The `<T>` part, which you’ve seen a few times before, indicates that this is | ||
<!-- The `<T>` part, which you’ve seen a few times before, indicates that this is | ||
a generic data type. Inside the declaration of our `enum`, wherever we see a `T`, | ||
we substitute that type for the same type used in the generic. Here’s an | ||
example of using `Option<T>`, with some extra type annotations: | ||
example of using `Option<T>`, with some extra type annotations: --> | ||
`<T>` の部分は、前に少し見たことがあると思いますが、これがジェネリックなデータ型であることを示しています。 `enum` の宣言内であれば、どこでも `T` を使うことができ、宣言内で記述していた共通の型をジェネリック内でこの型に置き換えます。型注釈を用いた`Option<T>`の使用例が以下になります。 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [strict] There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 検索すると"substitute A for B" が 「BをAで置き換える」で出て来るので、"the same type used in the generic"(ジェネリック内で登場する同一の型)を"that type"(こちらが There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. あー、なるほど。勘違いしていました。ごめんなさい。 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @KeenS 見返すと分かりにくい訳なので、 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 良いと思います。 |
||
|
||
```rust | ||
let x: Option<i32> = Some(5); | ||
``` | ||
|
||
In the type declaration, we say `Option<i32>`. Note how similar this looks to | ||
<!-- In the type declaration, we say `Option<i32>`. Note how similar this looks to | ||
`Option<T>`. So, in this particular `Option`, `T` has the value of `i32`. On | ||
the right-hand side of the binding, we make a `Some(T)`, where `T` is `5`. | ||
Since that’s an `i32`, the two sides match, and Rust is happy. If they didn’t | ||
match, we’d get an error: | ||
match, we’d get an error: --> | ||
この型の宣言を `Option<i32>` と言います。 `Option<T>` との違いに注目して下さい。そう、上記の `Option` では `T` の値は `i32` です。この束縛の右辺の `Some(T)` では、 `T` は `5` となります。それが `i32` なので、両辺の型が一致するため、Rustは満足します。型が不一致であれば、以下のようなエラーが発生します。 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
「この型宣言では There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
逆ですね。 「 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. はい、なんとなく「似ている事に注目」より「違いに注目」の方が日本語の言い回しかなと思ったのですがそのままでも良さそうです。 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. なら大丈夫です。 |
||
|
||
```rust,ignore | ||
let x: Option<f64> = Some(5); | ||
// error: mismatched types: expected `core::option::Option<f64>`, | ||
// found `core::option::Option<_>` (expected f64 but found integral variable) | ||
``` | ||
|
||
That doesn’t mean we can’t make `Option<T>`s that hold an `f64`! They just have | ||
to match up: | ||
<!-- That doesn’t mean we can’t make `Option<T>`s that hold an `f64`! They just have | ||
to match up: --> | ||
これは `f64` で特殊化した `Option<T>` が作れないという意味ではありませんからね!リテラルと宣言の型をぴったり合わせなければなりません。 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [nits] |
||
|
||
```rust | ||
let x: Option<i32> = Some(5); | ||
let y: Option<f64> = Some(5.0f64); | ||
``` | ||
|
||
This is just fine. One definition, multiple uses. | ||
<!-- This is just fine. One definition, multiple uses. --> | ||
これだけで結構です。1つの定義で、多くの用途が得られます。 | ||
|
||
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>`: | ||
<!-- 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>`: --> | ||
ジェネリクスにおいてジェネリックな型は1つまで、といった制限はありません。Rustの標準ライブラリに入っている類似の型 `Result<T, E>` について考えてみます。 | ||
|
||
```rust | ||
enum Result<T, E> { | ||
|
@@ -56,8 +64,9 @@ enum Result<T, E> { | |
} | ||
``` | ||
|
||
This type is generic over _two_ types: `T` and `E`. By the way, the capital letters | ||
can be any letter you’d like. We could define `Result<T, E>` as: | ||
<!-- This type is generic over _two_ types: `T` and `E`. By the way, the capital letters | ||
can be any letter you’d like. We could define `Result<T, E>` as: --> | ||
この型では `T` と `E` の_2つ_がジェネリックです。ちなみに、大文字の部分はあなたの好きな文字で構いません。もしあなたが望むなら `Result<T, E>` を、 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [Markdown]
ここの |
||
|
||
```rust | ||
enum Result<A, Z> { | ||
|
@@ -66,44 +75,54 @@ enum Result<A, Z> { | |
} | ||
``` | ||
|
||
if we wanted to. Convention says that the first generic parameter should be | ||
`T`, for ‘type’, and that we use `E` for ‘error’. Rust doesn’t care, however. | ||
<!-- if we wanted to. Convention says that the first generic parameter should be | ||
`T`, for ‘type’, and that we use `E` for ‘error’. Rust doesn’t care, however. --> | ||
のように定義できます。慣習としては、「Type」から第1ジェネリックパラメータは `T` であるべきですし、「Error」から `E` を用いるのですが、Rustは気にしません。 | ||
|
||
The `Result<T, E>` type is intended to be used to return the result of a | ||
computation, and to have the ability to return an error if it didn’t work out. | ||
<!-- The `Result<T, E>` type is intended to be used to return the result of a | ||
computation, and to have the ability to return an error if it didn’t work out. --> | ||
`Result<T, E>` 型は計算の結果を返すために使われることが想定されており、良い結果が出なかった場合にエラーの値を返す機能を持っています。 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
エラーは値が良い、悪いではなく処理が正常/異常終了したことを表わすので多少不適切かと思います。 |
||
|
||
## Generic functions | ||
<!-- ## Generic functions --> | ||
## ジェネリック関数 | ||
|
||
We can write functions that take generic types with a similar syntax: | ||
<!-- We can write functions that take generic types with a similar syntax: --> | ||
似た構文でジェネリックな型を取る関数を記述できます。 | ||
|
||
```rust | ||
fn takes_anything<T>(x: T) { | ||
// do something with x | ||
# // do something with x | ||
// xで何か行う | ||
} | ||
``` | ||
|
||
The syntax has two parts: the `<T>` says “this function is generic over one | ||
type, `T`”, and the `x: T` says “x has the type `T`.” | ||
<!-- The syntax has two parts: the `<T>` says “this function is generic over one | ||
type, `T`”, and the `x: T` says “x has the type `T`.” --> | ||
構文は2つのパーツから成ります。 `<T>` は「この関数は `T` という型がジェネリックである」ということであり、 `x: T` は「xは `T` 型である」という意味です。 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [strict]
「この関数は1つの型、 |
||
|
||
Multiple arguments can have the same generic type: | ||
<!-- Multiple arguments can have the same generic type: --> | ||
複数の引数が同じジェネリックな型を持つこともできます。 | ||
|
||
```rust | ||
fn takes_two_of_the_same_things<T>(x: T, y: T) { | ||
// ... | ||
} | ||
``` | ||
|
||
We could write a version that takes multiple types: | ||
<!-- We could write a version that takes multiple types: --> | ||
複数の型を取るバージョンを記述することも可能です。 | ||
|
||
```rust | ||
fn takes_two_things<T, U>(x: T, y: U) { | ||
// ... | ||
} | ||
``` | ||
|
||
## Generic structs | ||
<!-- ## Generic structs --> | ||
## ジェネリック構造体 | ||
|
||
You can store a generic type in a `struct` as well: | ||
<!-- You can store a generic type in a `struct` as well: --> | ||
また、 `struct` 内にジェネリックな型の値を保存することもできます。 | ||
|
||
```rust | ||
struct Point<T> { | ||
|
@@ -115,11 +134,13 @@ let int_origin = Point { x: 0, y: 0 }; | |
let float_origin = Point { x: 0.0, y: 0.0 }; | ||
``` | ||
|
||
Similar to functions, the `<T>` is where we declare the generic parameters, | ||
and we then use `x: T` in the type declaration, too. | ||
<!-- Similar to functions, the `<T>` is where we declare the generic parameters, | ||
and we then use `x: T` in the type declaration, too. --> | ||
関数と同様に、 `<T>` がジェネリックパラメータを宣言する場所であり、型宣言において `x: T` を使うのも同じです。 | ||
|
||
When you want to add an implementation for the generic `struct`, you just | ||
declare the type parameter after the `impl`: | ||
<!-- When you want to add an implementation for the generic `struct`, you just | ||
declare the type parameter after the `impl`: --> | ||
ジェネリックな `struct` に実装を追加したい場合、 `impl` の後に型パラメータを宣言するだけです。 | ||
|
||
```rust | ||
# struct Point<T> { | ||
|
@@ -134,11 +155,12 @@ impl<T> Point<T> { | |
} | ||
``` | ||
|
||
So far you’ve seen generics that take absolutely any type. These are useful in | ||
<!-- So far you’ve seen generics that take absolutely any type. These are useful in | ||
many cases: you’ve already seen `Option<T>`, and later you’ll meet universal | ||
container types like [`Vec<T>`][Vec]. On the other hand, often you want to | ||
trade that flexibility for increased expressive power. Read about [trait | ||
bounds][traits] to see why and how. | ||
bounds][traits] to see why and how. --> | ||
ここまででありとあらゆる型をとる事のできるジェネリクスについて見てきました。多くの場合これらは有用です。 `Option<T>` は既に見た通りですし、のちに `Vec<T>` のような普遍的なコンテナ型を知ることになるでしょう。一方で、その柔軟性と引き換えに表現力を増加させたくなることもあります。それは何故か、そしてその方法を知るためには [トレイト境界][traits] を読んで下さい。 | ||
|
||
[traits]: traits.html | ||
[Vec]: ../std/vec/struct.Vec.html |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nits]
おそらくここのenoughは「十分理解出来るまで話した」ではなく「理論的な話はこれでもうたくさんだ」のニュアンスが含まれているのですがそれっぽい訳ってありますかね?(相談)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
「さて、型理論はもう十分です」ですかね、「もう沢山です」でも良いかもしれないですがちょっと言い回しがキツイかもしれません
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
素晴しいと思います。ちょうど(full ofでなくて)'enough'のニュアンスになってると思います。