-
Notifications
You must be signed in to change notification settings - Fork 72
4.12. Enums #81
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.12. Enums #81
Changes from 2 commits
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,7 +1,9 @@ | ||
% Enums | ||
% 列挙型 | ||
<!-- % Enums --> | ||
|
||
An `enum` in Rust is a type that represents data that could be one of | ||
several possible variants: | ||
<!-- An `enum` in Rust is a type that represents data that could be one of | ||
several possible variants: --> | ||
Rustの `enum` は、いくつかのヴァリアントのうちからどれか一つをとるデータを表す型です。 | ||
|
||
```rust | ||
enum Message { | ||
|
@@ -12,17 +14,27 @@ enum Message { | |
} | ||
``` | ||
|
||
Each variant can optionally have data associated with it. The syntax for | ||
<!-- Each variant can optionally have data associated with it. The syntax for | ||
defining variants resembles the syntaxes used to define structs: you can | ||
have variants with no data (like unit-like structs), variants with named | ||
data, and variants with unnamed data (like tuple structs). Unlike | ||
separate struct definitions, however, an `enum` is a single type. A | ||
value of the enum can match any of the variants. For this reason, an | ||
enum is sometimes called a ‘sum type’: the set of possible values of the | ||
enum is the sum of the sets of possible values for each variant. | ||
|
||
We use the `::` syntax to use the name of each variant: they’re scoped by the name | ||
of the `enum` itself. This allows both of these to work: | ||
enum is the sum of the sets of possible values for each variant. --> | ||
各ヴァリアントは、自身に関連するデータを持つこともできます。 | ||
ヴァリアントの定義のための構文は、構造体を定義するのに使われる構文と似ており、 | ||
(unit-like構造体のような) データを持たないヴァリアント、名前付きデータを持つヴァリアント、 (タプル構造体のような) 名前なしデータを持つヴァリアントがありえます。 | ||
しかし、別々に構造体を定義する場合とは異なり、 `enum` は一つの型です。 | ||
列挙型の値はどのヴァリアントにもマッチしうるのです。 | ||
このことから、列挙型は「直和型」(sum type) と呼ばれることもあります。 | ||
列挙型としてありうる値の集合は、各ヴァリアントとしてありうる値の集合の和であるためです。 | ||
|
||
<!-- We use the `::` syntax to use the name of each variant: they’re scoped by the name | ||
of the `enum` itself. This allows both of these to work: --> | ||
各ヴァリアントの名前を使うためには、 `::` 構文を使います。 | ||
`enum` 自体の名前によってスコープするのです。 | ||
これにより、以下は動きます。 | ||
|
||
```rust | ||
# enum Message { | ||
|
@@ -38,36 +50,50 @@ enum BoardGameTurn { | |
let y: BoardGameTurn = BoardGameTurn::Move { squares: 1 }; | ||
``` | ||
|
||
Both variants are named `Move`, but since they’re scoped to the name of | ||
the enum, they can both be used without conflict. | ||
<!-- Both variants are named `Move`, but since they’re scoped to the name of | ||
the enum, they can both be used without conflict. --> | ||
どちらのヴァリアントも `Move` という名前ですが、列挙型の名前でスコープされているため、衝突することなく使うことができます。 | ||
|
||
A value of an enum type contains information about which variant it is, | ||
<!-- A value of an enum type contains information about which variant it is, | ||
in addition to any data associated with that variant. This is sometimes | ||
referred to as a ‘tagged union’, since the data includes a ‘tag’ | ||
indicating what type it is. The compiler uses this information to | ||
enforce that you’re accessing the data in the enum safely. For instance, | ||
you can’t simply try to destructure a value as if it were one of the | ||
possible variants: | ||
possible variants: --> | ||
列挙型の値は、ヴァリアントに関連するデータに加え、その値自身がどのヴァリアントであるかという情報を持っています。 | ||
これを「タグ付きユニオン」(tagged union) ということもあります。 | ||
データが、それ自身がどの型なのかを示す「タグ」をもっているためです。 | ||
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. この"type"は「型」の訳で良いと思います。 Wikipediaの"Tagged Union"の記事(https://en.wikipedia.org/wiki/Tagged_union) には
という似た文があり、そちらの"type"は明らかに「型」なので、"タグはどの「型」かを示すもの"という認識は正しいと思います。 また、「種類」というような意味の「タイプ」だとしたら、"what type it is" ではなく、"which type it is" になりそうな気がします。 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 | ||
fn process_color_change(msg: Message) { | ||
let Message::ChangeColor(r, g, b) = msg; // compile-time error | ||
# // let Message::ChangeColor(r, g, b) = msg; // compile-time error | ||
let Message::ChangeColor(r, g, b) = msg; // コンパイル時エラー | ||
} | ||
``` | ||
|
||
Not supporting these operations may seem rather limiting, but it’s a limitation | ||
<!-- Not supporting these operations may seem rather limiting, but it’s a limitation | ||
which we can overcome. There are two ways: by implementing equality ourselves, | ||
or by pattern matching variants with [`match`][match] expressions, which you’ll | ||
learn in the next section. We don’t know enough about Rust to implement | ||
equality yet, but we’ll find out in the [`traits`][traits] section. | ||
equality yet, but we’ll find out in the [`traits`][traits] section. --> | ||
こういった操作が許されないことで制限されているように感じられるかもしれませんが、この制限は克服できます。 | ||
それには二つの方法があります。 | ||
一つは等値性を自分で実装する方法、もう一つは次のセクションで学ぶ [`match`][match] 式でヴァリアントのパターンマッチを行う方法です。 | ||
等値性を実装するにはRustについてまだ知るべきことがありますが、 [`トレイト`][traits] のセクションに書いてあります。 | ||
|
||
[match]: match.html | ||
[if-let]: if-let.html | ||
[traits]: traits.html | ||
|
||
# Constructors as functions | ||
<!-- # Constructors as functions --> | ||
# 関数としてのコンストラクタ | ||
|
||
An enum’s constructors can also be used like functions. For example: | ||
<!-- An enum’s constructors can also be used like functions. For example: --> | ||
列挙型のコンストラクタも、関数のように使うことができます。 | ||
例えばこうです。 | ||
|
||
```rust | ||
# enum Message { | ||
|
@@ -76,7 +102,8 @@ An enum’s constructors can also be used like functions. For example: | |
let m = Message::Write("Hello, world".to_string()); | ||
``` | ||
|
||
Is the same as | ||
<!-- Is the same as --> | ||
これは、以下と同じです。 | ||
|
||
```rust | ||
# enum Message { | ||
|
@@ -89,10 +116,12 @@ fn foo(x: String) -> Message { | |
let x = foo("Hello, world".to_string()); | ||
``` | ||
|
||
This is not immediately useful to us, but when we get to | ||
<!-- This is not immediately useful to us, but when we get to | ||
[`closures`][closures], we’ll talk about passing functions as arguments to | ||
other functions. For example, with [`iterators`][iterators], we can do this | ||
to convert a vector of `String`s into a vector of `Message::Write`s: | ||
to convert a vector of `String`s into a vector of `Message::Write`s: --> | ||
また、すぐに役立つことではないのですが、[`クロージャ`][closures] までいくと、関数を他の関数へ引数として渡す話をします。 | ||
例えば、これを [`イテレータ`][iterators] とあわせることで、 `String` のベクタから `Message::Write` へ変換することができます。 | ||
|
||
```rust | ||
# enum Message { | ||
|
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]
struct, enumは「構造体」「列挙型」にしてあるので「タグ付き共用体」の方が馴染むかもしれません。