成果物
参考
定義
fn main() { println!("{:?}", IpAddrKind::V4); println!("{:?}", IpAddrKind::V6); } #[derive(Debug)] enum IpAddrKind { V4, V6, }
匿名タプル構造体型
fn main() { println!("{:?}", IpAddr::V4(127, 0, 0, 1)); // error[E0277]: `IpAddr` doesn't implement `std::fmt::Display` println!("{:?}", IpAddr::V6(String::from("::1"))); // error[E0277]: `IpAddr` doesn't implement `std::fmt::Display` } enum IpAddr { V4(u8,u8,u8,u8), V6(String), }
整数値以外の型をセットできる!
値なし、匿名構造体型、タプル構造体型
fn main() { println!("{}", Message::Move{x:0,y:0} == Message::Move{x:0,y:0}); println!("{}", Message::Move{x:0,y:0} == Message::Move{x:1,y:1}); println!("{}", Message::Move{x:0,y:0} == Message::Quit); use std::mem; println!("{}", mem::discriminant(&Message::Move{x:0,y:0}) == mem::discriminant(&Message::Move{x:0,y:0})); println!("{}", mem::discriminant(&Message::Move{x:0,y:0}) == mem::discriminant(&Message::Move{x:1,y:1})); println!("{}", mem::discriminant(&Message::Move{x:0,y:0}) == mem::discriminant(&Message::Quit)); } // メッセージをenumで定義する #[derive(PartialOrd, PartialEq, Debug)] enum Message { Quit, Move { x: i32, y: i32 }, Write(String), ChangeColor(i32, i32, i32), }
列挙型値にセットしたい値は匿名構造体として表現する。名前なしなら匿名タプル構造体型。名前付きなら匿名構造体型。
メソッド実装
fn main() { let m = Message::Move{x:0,y:0}; m.call(); Message::Move{x:1,y:1}.call(); Message::Quit.call(); Message::Write(String::from("hello")).call(); Message::ChangeColor(255,0,0).call(); } // メッセージをenumで定義する #[derive(PartialOrd, PartialEq, Debug)] enum Message { Quit, Move { x: i32, y: i32 }, Write(String), ChangeColor(i32, i32, i32), } // enumにメソッドを実装する impl Message { fn call(&self) { println!("call {:?}", self); } }
enumにメソッドを実装できる! 構造体とおなじ。
構造体との違い
列挙型のほうが大きなグルーピングができる。(列挙は構造体定義の配列みたいなイメージ)
enum Message { Quit, Move { x: i32, y: i32 }, Write(String), ChangeColor(i32, i32, i32), }
上記のメッセージ4種を構造体で定義すると以下。
struct QuitMessage; struct MoveMessage { x: i32, y: i32, } struct Write(String); // タプル構造体 struct ChangeColor(i32, i32, i32); // タプル構造体
個別の型になってしまう。
C/C++との比較
言語 | 概要 |
---|---|
C/C++ | 各整数値とその集合に名前をつけてグルーピングしたもの |
Rust | 各構造体とその集合に名前をつけてグルーピングしたもの。メソッド実装も可 |
Rustのenumはクラスの中でも上位(抽象)にあるところで使うイメージ? (そもそもオブジェクト指向言語のクラスと比べるのが間違っていると思うけど)
対象環境
- Raspbierry pi 3 Model B+
- Raspbian stretch 9.0 2018-11-13
- bash 4.4.12(1)-release
$ uname -a Linux raspberrypi 4.19.42-v7+ #1219 SMP Tue May 14 21:20:58 BST 2019 armv7l GNU/Linux
前回まで
- Rustを学んでみたい(プログラミング言語)
- Rustの環境構築
- RustでHelloWorld
- Rustの和訳ドキュメント
- Cargoでプロジェクト作成・ビルド・実行
- クレートとは?
- Rustで関数を使ってみる
- Rustでモジュールを使ってみる
- Rustで乱数を生成する(rand)
- Rustで標準入力する(std::io::stdin().read_line())
- RustでMatch判定する(match)
- Rustでprintとread_lineを1行にする方法
- Rustで数当てゲーム
- クレート名にドット.が使えない
- Rustの変数と可変性(let, mut) error[E0384]: cannot assign twice to immutable variable
x
- Rustのimmutable束縛とconst定数の違い
- RustのREPL、evcxrのインストールに失敗した
- Rustでコンパイルするときの変数未使用warningを消す
- Rustの変数(再代入、再宣言(シャドーイング))
- Rustのシャドーイングについて
- イミュータブルについて(副作用)
- Rustの定数(const)
- Rustのデータ型(数値)
- Rustのデータ型(論理)
- Rustのデータ型(文字)
- Rustのデータ型(タプル)
- Rustのデータ型(配列)
- Rustの関数
- Rustのif式
- Rustのくりかえし文(loop)
- Rustのくりかえし文(while)
- Rustのくりかえし文(for)
- Rustの所有権(ムーブ)
- Rustの所有権(関数)
- Rustの所有権(スライス)
- Rustの構造体(定義とインスタンス化)
- Rustの構造体(プログラム例)
- Rustの構造体(メソッド)