データを持つenum
バリアントに値を関連付けます。
「データを持つenum」はCoddyKit上の無料Learn Rust Codingレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはLearn Rust Coding学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Learn Rust Codingコースには全4レッスンが含まれています。
バリアントはデータを持てる
これまでのバリアントは名前だけでした。Rustでは、バリアントはかっこの中にデータを持つこともできます。
これにより、1つのenumで値の種類と値そのものの両方を表せます。
enum Message {
Quit,
Move(i32, i32),
Write(String),
}1つの値を持つバリアント
バリアントに1つのデータを付けるには、かっこの中に型を記述します。
ここでCelsius(f64)は、Celsiusバリアントがf64型の数値を持つことを意味します。値を作成するときに、その数値を渡します。
enum Temperature {
Celsius(f64),
Fahrenheit(f64),
}
fn main() {
let t = Temperature::Celsius(21.5);
println!("Created a temperature");
}複数の値を持つバリアント
バリアントは、カンマで区切った複数の値を持つこともできます。
Move(i32, i32)は2つの整数を格納します。たとえば、x座標とy座標です。作成時に両方を渡します。
enum Shape {
Circle(f64),
Rectangle(f64, f64),
}
fn main() {
let r = Shape::Rectangle(3.0, 4.0);
println!("Made a rectangle");
}matchでデータを取り出す
バリアントの内部にあるデータを読み取るには、パターン内で名前を付けます。その名前は、そのアームで使用できる変数になります。
ここでは、Shape::Circle(r)によって格納された半径がrに束縛されます。
enum Shape {
Circle(f64),
Rectangle(f64, f64),
}
fn main() {
let s = Shape::Circle(2.0);
match s {
Shape::Circle(r) => println!("radius {}", r),
Shape::Rectangle(w, h) => println!("{} x {}", w, h),
}
}束縛した値の使用
データを名前に束縛すると、他の変数と同じように、その値を使って計算できます。
このプログラムは図形をmatchして面積を計算し、その結果をmatchから返します。
enum Shape {
Circle(f64),
Rectangle(f64, f64),
}
fn main() {
let s = Shape::Rectangle(3.0, 4.0);
let area = match s {
Shape::Circle(r) => 3.14 * r * r,
Shape::Rectangle(w, h) => w * h,
};
println!("area = {}", area);
}バリアントごとに異なるデータ
各バリアントは異なる形のデータを持つことができ、データをまったく持たないバリアントも定義できます。
この柔軟性により、enumは表現力に優れています。1つの型で、互いに異なる多くのケースをモデル化できます。
enum Message {
Quit,
Move(i32, i32),
Write(String),
}構造体のようなバリアント
バリアントでは、構造体と同じように中かっこを使って名前付きフィールドを持たせることができます。これにより、各フィールドの意味が明確になります。
各フィールドに名前を付けて構築し、同じように名前を使ってマッチさせます。
enum Event {
Click { x: i32, y: i32 },
KeyPress(char),
}
fn main() {
let e = Event::Click { x: 10, y: 20 };
match e {
Event::Click { x, y } => println!("click at {},{}", x, y),
Event::KeyPress(c) => println!("key {}", c),
}
}バリアント内の文字列
バリアントには、Stringのような所有権を持つデータを格納できます。マッチングすると、そのテキストにアクセスできます。
注: 値によるマッチングではデータがムーブされますが、ここではすぐに使うため問題ありません。
enum Message {
Write(String),
Quit,
}
fn main() {
let m = Message::Write(String::from("hello"));
match m {
Message::Write(text) => println!("text: {}", text),
Message::Quit => println!("bye"),
}
}標準の Option 列挙型
Rust組み込みのOption<T>はデータを持つ列挙型です。Some(T)は値を保持し、Noneは何も保持しません。
これは、nullを使わずに「値があるかもしれない」状態をRustで表す方法です。独自の列挙型と同じようにマッチさせます。
fn main() {
let maybe: Option<i32> = Some(5);
match maybe {
Some(n) => println!("got {}", n),
None => println!("nothing"),
}
}組み合わせる
この完全なプログラムでは、温度をモデル化し、matchの中で摂氏の値を華氏に変換します。
バリアントやその値を変更して、もう一度実行してみてください。
enum Temperature {
Celsius(f64),
Fahrenheit(f64),
}
fn main() {
let t = Temperature::Celsius(25.0);
let f = match t {
Temperature::Celsius(c) => c * 9.0 / 5.0 + 32.0,
Temperature::Fahrenheit(f) => f,
};
println!("{} F", f);
}データを持つバリアントを使う場面
各ケースに自然に追加情報が伴う場合は、データを持つバリアントを使います。
Circleには半径が必要です。Writeメッセージにはテキストが必要です。Moveには座標が必要です。
データをバリアントと一緒にまとめることで、関連する情報をまとめて型安全に扱えます。
簡単な確認
データを持つ列挙型についての理解を確認しましょう。
まとめ
列挙型のバリアントはデータを持てることを学びました。単一の値、複数の値、構造体のような名前付きフィールド、または何も持たない形にできます。
Circle(r)のように、matchパターンで名前を付けることでデータを読み取ります。標準のOption型も同じ仕組みで動作します。次はガードとバインディングを使ってマッチをさらに細かく制御します。
よくある質問
「データを持つenum」レッスンは無料ですか?
はい。「データを持つenum」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Learn Rust Codingコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Learn Rust Codingコースには全4レッスンが含まれています。
「データを持つenum」で何を学びますか?
バリアントに値を関連付けます。 ブラウザで直接実行するハンズオンコードでLearn Rust Codingを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Learn Rust Codingを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのLearn Rust Codingは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。
「データを持つenum」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このLearn Rust Codingレッスンでコードを書いて実行できますか?
はい。すべてのLearn Rust Codingレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。