目次
列挙型 enum
列挙型は、相互に関連する離散データの有限セットを表すために使用される型であり、これらの値は、異なる整数、文字列、またはその他の種類のオブジェクトにすることができます。列挙体の要素は「メンバー」と呼ばれます。Rust 言語では、列挙体のメンバーは構造体と見なすことができます。もちろん、列挙体は別の列挙体をネストすることができます。
定義と宣言
Rustでは、列挙型はキーワードenumで定義できます。
enum MyEnum {
Variant1,
Variant2,
Variant3,
//...
VariantN,
}
enum は enumerate/enumeration の頭字語で、MyEnum はカスタム列挙名です。
Variant は変数という意味で、「バリアント」と訳す人もいますが、 C/C++ 言語では「メンバー」という名前を使うのが適切だと思います。
Variant の数 N は制限する必要があり、変数が多すぎると意味がありません。また、N>=2 の場合はメンバーが存在しないか、単一のメンバーは意味がありません。
列挙型を使用すると、さまざまな状況に応じて限られた値のセットを定義できます。これは、複数の可能な状態またはオプションを表す必要がある状況で役立ちます。以下に、一般的な列挙型の典型的な例をいくつか示します。
例 1: 色の列挙
Color 列挙は、赤、緑、青など、色の取り得るさまざまな値を表します。
enum Color {
Red,
Green,
Blue,
}
例 2: 方向の列挙
Direction 列挙型は、上、下、左、右など、方向に取り得るさまざまな値を表します。
enum Direction {
Up,
Down,
Left,
Right,
}
例 3: 平日の列挙
Weekday 列挙は、1 週間の 7 日間の列挙など、さまざまな曜日を表します。
enum Weekday {
Sunday,
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
}
クラス C enum C に似た
C/C++ 言語の列挙型メンバーは、列挙型定数とも呼ばれる、signed int 定数のみを使用できます。Rust に C スタイルの列挙型がある場合、その列挙型のメンバーがすべてユニット構造であることが満たされなければなりません。
プリントアウト
#[derive(Debug)] を使用して出力を簡略化します。形式は println!("{ :? }", MyEnum :: VariantN); です。
#[derive(Debug)]
enum Number {
Zero,
One,
Two,
Three,
}
fn main() {
println!("zero is {:?}", Number::Zero);
println!("one is {:?}", Number::One);
println!("Two is {:?}", Number::Two);
println!("Three is {:?}", Number::Three);
}
出力:
ゼロはゼロ
1 は 1
2 は 2
3 は 3
整数に強制する
#[derive(Debug)] を使用せず、強制的に整数に変換して出力します。
enum Number {
Zero,
One,
Two,
Three,
}
fn main() {
println!("zero is {}", Number::Zero as i32);
println!("one is {}", Number::One as i32);
println!("Two is {}", Number::Two as i32);
println!("Three is {}", Number::Three as i32);
}
出力:
ゼロは 0、1
は 1、2
は 2、3
は 3
C のような列挙型は、代入によって一連の離散整数に変換することもできます。
#![allow(dead_code)]
#[derive(Debug)]
enum Number {
Zero,
One,
Two,
Five = 5,
Six,
}
fn main() {
println!("zero is {}", Number::Zero as i32);
println!("one is {}", Number::One as i32);
println!("Five is {}", Number::Five as i32);
println!("Six is {}", Number::Six as i32);
}
出力:
0
1
5
6
注: 列挙メンバー Two はプログラム全体で呼び出されていません。#![allow(dead_code)] を使用して警告を除外できます。この行がないと、上記のプログラムはコンパイルおよび実行中に結果を出力できますが、同時に警告: 警告: バリアント `Two` は構築されません。
例 1: 平日の列挙
Weekday 列挙では、デフォルトの日曜日から土曜日が整数 0 ~ 6 に対応するのではなく、月曜日から日曜日が整数 1 ~ 7 に対応するように値が割り当てられます。
#![allow(dead_code)]
enum Weekday {
Sunday = 7,
Monday = 1,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
}
fn main() {
println!("Sunday is {}", Weekday::Sunday as i32);
println!("Tuesday is {}", Weekday::Tuesday as i32);
println!("Saturday is {}", Weekday::Saturday as i32);
}
出力:
日曜日は 7
火曜日は 2
土曜日は 6
例 2: HttpStatus 列挙
HttpStatus 列挙は、さまざまな HTTP ステータス コードを示します。たとえば、200 は成功を示し、404 はページが見つからないことを示し、500 は内部サーバー エラーを示します。合計で約 100 のメンバーがあり、列挙は次のとおりです。
#![allow(dead_code)]
enum HttpStatus {
Continue = 100, //"CONTINUE" 继续
SwitchingProtocols, //"SWITCHING_PROTOCOLS" 切换协议
Processing, //"PROCESSING" 执行
Checkpoint, //"CHECKPOINT" 检查点
OK = 200, //"OK" OK
CREATED, //"Created" 创建
ACCEPTED, //"Accepted" 接受
NonAuthoritativeInformation, //"NON_AUTHORITATIVE_INFORMATION" 非权威信息
NoContent, //"NO_CONTENT" 没有内容
ResetContent, //"RESET_CONTENT" 重置内容
PartialContent, //"PARTIAL_CONTENT" 部分内容
MultiStatus, //"MULTI_STATUS" 多个状态
AlreadyReported, //"ALREADY_REPORTED" 已发
IMUsed = 226, //"IM_USED" 已过时
MultipleChoices = 300, //"MULTIPLE_CHOICES" 多选择
MovedPermanently, //"MOVED_PERMANENTLY" 永久移动
FOUND, //"Found" 找到
MovedTemporarily, //"MOVED_TEMPORARILY"
SeeOther, //"SEE_OTHER" 参见其它
NotModified, //"NOT_MODIFIED" 未修改
UseProxy, //"USE_PROXY"),
TemporaryRedirect, //"TEMPORARY_REDIRECT" 暂时重定向
PermanentRedirect, //"PERMANENT_REDIRECT" 永久重定向
//......
BadRequest = 400, //"BAD_REQUEST" 错误请求
Unauthorized, //"UNAUTHORIZED" 未经授权
PaymentRequired, //"PAYMENT_REQUIRED" 付费请求
Forbidden, //"FORBIDDEN" 禁止
NotFound, //"NOT_FOUND" 未找到
MethodNotAllowed, //"METHOD_NOT_ALLOWED" 方法不容许
NotAcceptable, //"NOT_ACCEPTABLE" 方法不接受
//......
InternalServerError = 500, // "INTERNAL_SERVER_ERROR" 服务器遇到了意料不到的情况,不能完成客户的请求
NotImplemented, //"NOT_IMPLEMENTED" 服务器不支持实现请求所需要的功能
BadGateway, //"BAD_GATEWAY" 从上游服务器接收到无效的响应
ServiceUnavailable, //"SERVICE_UNAVAILABLE" 服务不可用
GatewayTimeout, //"GATEWAY_TIMEOUT") 网关不能及时地从远程服务器获得应答
//......
}
fn main() {
println!("OK is {}", HttpStatus::OK as i32);
println!("Bad Request is {}", HttpStatus::BadRequest as i32);
}
出力:
OK は 200、
Bad リクエストは 400
例 3: 色の列挙
6桁の16進数で表される色を出力するには{:06x}形式を使用します
enum Color {
Red = 0xff0000,
Green = 0x00ff00,
Blue = 0x0000ff,
}
fn main() {
println!("roses are #{:06x}", Color::Red as i32);
println!("leaves are #{:06x}", Color::Green as i32);
println!("violets are #{:06x}", Color::Blue as i32);
println!("red is {}", Color::Red as i32);
println!("green is {}", Color::Green as i32);
println!("blue is {}", Color::Blue as i32);
}
出力:
バラは #ff0000
葉は #00ff00
スミレは #0000ff
赤は 16711680
緑は 65280
青は 255
パターンマッチング
Enum 型は、Rust でパターン マッチングと組み合わせてよく使用され、enum 型の値に基づいてさまざまな操作を実行します。
一致式
match 式を使用すると、列挙型バリアントをパターン マッチングし、一致したバリアントに従って対応するコード ブロックを実行できます。その構文は次のとおりです。
match value {
pattern1 => {
// 如果 value 匹配了 pattern1
},
pattern2 => {
// 如果 value 匹配了 pattern2
},
// 其他模式...
}
たとえば、Red、Green、Blue の 3 つのメンバーを含む Color という名前の列挙型を定義します。各メンバーは、異なる色を表すために使用される法的な識別子です。
enum Color {
Red,
Green,
Blue,
}
上記の Color 列挙型の場合、パターン マッチングを使用して、対応する操作を実行できます。
fn print_color(color: Color) {
match color {
Color::Red => println!("The color is Red"),
Color::Green => println!("The color is Green"),
Color::Blue => println!("The color is Blue"),
}
}
上記の例では、関数 print_color は Color 型のパラメーターを受け取り、パターン マッチングに match を使用します。渡された色の値に従って、対応する操作が実行されます。
列挙メソッド
メソッドをカスタマイズして、各メンバーに対応する値を定義することもできます。
#![allow(dead_code)]
enum Color {
Red,
Green,
Blue,
Yellow,
Magenta,
Cyan,
}
impl Color {
fn to_rgb(&self) -> (u8, u8, u8) {
match self {
Color::Red => (255, 0, 0),
Color::Green => (0, 255, 0),
Color::Blue => (0, 0, 255),
Color::Yellow => (255, 255, 0),
Color::Magenta => (255, 0, 255),
Color::Cyan => (0, 255, 255),
}
}
}
fn main() {
let red = Color::Red;
let red_rgb = red.to_rgb();
println!("RGB value of red: {:?}", red_rgb);
let yellow = Color::Yellow;
let yellow_rgb = yellow.to_rgb();
println!("RGB value of yellow: {:?}", yellow_rgb);
}
上記の例では、Color 列挙型の to_rgb メソッドを実装して、色を RGB 値に変換しました。
要約すると、Rust の列挙型は強力なパターン マッチング機能を提供し、列挙型を非常に柔軟で信頼性が高く、さまざまなシナリオやデータ処理のニーズに適したものにします。この記事では、最初に C に似た列挙型についてのみ学習し、他の分類については次の章で分解します。