Skip to content

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

Merged
merged 3 commits into from
Feb 13, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 49 additions & 20 deletions 1.6/ja/book/enums.md
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 {
Expand All @@ -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 {
Expand All @@ -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) ということもあります。
データが、それ自身がどの型なのかを示す「タグ」をもっているためです。
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

タグ付き共用体のタグはどの型かではなくどのヴァリアントかを表すので「型」ではなく「タイプ」の方が正確かと思います。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

この"type"は「型」の訳で良いと思います。
各ヴァリアントとは値がとりうる型であり、それぞれが異なる型であるからです。

Wikipediaの"Tagged Union"の記事(https://en.wikipedia.org/wiki/Tagged_union) には

Only one of the types can be in use at any one time, and a tag field explicitly indicates which one is in use.

という似た文があり、そちらの"type"は明らかに「型」なので、"タグはどの「型」かを示すもの"という認識は正しいと思います。

また、「種類」というような意味の「タイプ」だとしたら、"what type it is" ではなく、"which type it is" になりそうな気がします。

Copy link
Member

Choose a reason for hiding this comment

The 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 {
Expand All @@ -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 {
Expand All @@ -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 {
Expand Down
6 changes: 6 additions & 0 deletions TranslationTable.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,10 @@
| closure | クロージャ
| coercion | 型強制
| comma | カンマ
| compile-time error | コンパイル時エラー
| compiler | コンパイラ
| constant | 定数
| constructor | コンストラクタ
| crate | クレート
| dangling | ダングリング
| declaration statement | 宣言文
Expand All @@ -45,6 +47,7 @@
| documentation test | ドキュメンテーションテスト
| early return | 早期リターン
| enum | 列挙型
| equality | 等値性
| expression statement | 式文
| feature | フィーチャ
| generic parameter | ジェネリックパラメータ
Expand Down Expand Up @@ -102,9 +105,11 @@
| string interpolation | 文字列インターポーレーション
| struct | 構造体
| structure | ストラクチャ
| sum type | 直和型
| symbol | シンボル
| syntactic sugar | 糖衣構文
| system | システム
| tagged union | タグ付き共用体
| tick | クオート
| trait | トレイト
| type inference | 型推論
Expand All @@ -115,6 +120,7 @@
| unsized type | サイズ不定型
| variable | 変数
| variable binding | 変数束縛
| variant | ヴァリアント
| vector | ベクタ
| warning | ウォーニング
| wildcard | ワイルドカード