<style> /* basic design */ .reveal h1, .reveal h2, .reveal h3, .reveal h4, .reveal h5, .reveal h6, .reveal section, .reveal table, .reveal li, .reveal blockquote, .reveal th, .reveal td, .reveal p { font-family: 'Meiryo UI', 'Source Sans Pro', Helvetica, sans-serif, 'Helvetica Neue', 'Helvetica', 'Arial', 'Hiragino Sans', 'ヒラギノ角ゴシック', YuGothic, 'Yu Gothic'; text-align: left; line-height: 1.6; letter-spacing: normal; text-shadow: none; word-wrap: break-word; color: #444; } .reveal h1, .reveal h2, .reveal h3, .reveal h4, .reveal h5, .reveal h6 {font-weight: bold;} .reveal h1, .reveal h2, .reveal h3 {color: #2980b9;} .reveal th {background: #DDD;} .reveal section img {background:none; border:none; box-shadow:none; max-width: 95%; max-height: 95%;} .reveal blockquote {width: 90%; padding: 0.5vw 3.0vw;} .reveal table {margin: 1.0vw auto;} .reveal code {line-height: 1.2;} .reveal p, .reveal li {padding: 0vw; margin: 0vw;} .reveal .box {margin: -0.5vw 1.5vw 2.0vw -1.5vw; padding: 0.5vw 1.5vw 0.5vw 1.5vw; background: #EEE; border-radius: 1.5vw;} /* table design */ .reveal table {background: #f5f5f5;} .reveal th {background: #444; color: #fff;} .reveal td {position: relative; transition: all 300ms;} .reveal tbody:hover td { color: transparent; text-shadow: 0 0 3px #aaa;} .reveal tbody:hover tr:hover td {color: #444; text-shadow: 0 1px 0 #fff;} /* blockquote design */ .reveal blockquote { width: 90%; padding: 0.5vw 0 0.5vw 6.0vw; font-style: italic; background: #f5f5f5; } .reveal blockquote:before{ position: absolute; top: 0.1vw; left: 1vw; content: "\f10d"; font-family: FontAwesome; color: #2980b9; font-size: 3.0vw; } /* font size */ .reveal h1 {font-size: 5.0vw;} .reveal h2 {font-size: 4.0vw;} .reveal h3 {font-size: 2.8vw;} .reveal h4 {font-size: 2.6vw;} .reveal h5 {font-size: 2.4vw;} .reveal h6 {font-size: 2.2vw;} .reveal section, .reveal table, .reveal li, .reveal blockquote, .reveal th, .reveal td, .reveal p {font-size: 2.2vw;} .reveal code {font-size: 1.6vw;} /* new color */ .red {color: #EE6557;} .blue {color: #16A6B6;} /* split slide */ #right {left: -18.33%; text-align: left; float: left; width: 50%; z-index: -10;} #left {left: 31.25%; text-align: left; float: left; width: 50%; z-index: -10;} </style> <style> /* specific design */ .reveal h2 { padding: 0 1.5vw; margin: 0.0vw 0 2.0vw -2.0vw; border-left: solid 1.2vw #2980b9; border-bottom: solid 0.8vw #d7d7d7; } </style> <!-- --------------------------------------------------------------------------------------- --> # Rust勉強会 第3回 ## 4章 構造体で構造化! **2020/08/21 堀川由人** --- ## 本日のメニュー 1. 構造体の定義 1. プログラム例 1. メソッド記法 プレゼン20分くらい+議論10分位で18:30前後終了を目指します。 --- ## 構造体の定義 ---- ### struct構文 構造体を定義する ```rust struct User { username: String, email: String, sign_in_count: u64, active: bool, // ここの,は無くてもok } ``` ---- ### インスタンス作成 インスタンスをつくる(順番は気にしなくてOK) ```rust let user1 = User { email: String::from("someone@example.com"), username: String::from("someusername123"), active: true, sign_in_count: 1, }; ``` ---- ### フィールドの変更(2/2) エラーになる例 ```rust let user1 = User { email: String::from("someone@example.com"), username: String::from("someusername123"), active: true, sign_in_count: 1, }; user1.active = false ``` ---- ### フィールドの変更(2/2) ここでもフィールドを変更する場合は`mut`が必要 ```rust let mut user1 = User { email: String::from("someone@example.com"), username: String::from("someusername123"), active: true, sign_in_count: 1, }; user1.active = false ``` ---- ### インスタンスを作る関数(1/2) 2つの`String`引数を取って`User`を返す ```rust fn build_user(email: String, username: String) -> User { User { email: email, username: username, active: true, sign_in_count: 1, } } ``` ---- ### インスタンスを作る関数(2/2) 実は省略可能 ```rust fn build_user(email: String, username: String) -> User { User { email, username, active: true, sign_in_count: 1, } } ``` ---- ### インスタンスの構成(他からの参照) 他の`user2`を定義. ただし足りないものは`user1`から ```rust let user1 = User { email: String::from("someone@example.com"), username: String::from("someusername123"), active: true, sign_in_count: 1, }; let user2 = User { email: String::from("another@example.com"), username: String::from("anotherusername567"), ..user1 }; ``` ---- ### ほぼタプルの構造体 引数の順番のみが重要な場合 ```rust struct Color(i32, i32, i32); struct Point(i32, i32, i32); let black = Color(0, 0, 0); let origin = Point(0, 0, 0); ``` (個人的にはRGBかBGRを明記したいので避けたい) --- ## プログラム例 ---- ### 長方形の面積(愚直に) ```rust fn main() { let width1 = 30; let height1 = 50; println!("The area is {}.", area(width1, height1)); } fn area(width: u32, height: u32) -> u32 { width * height } ``` ---- ### 長方形の面積(構造体) ```rust struct Rectangle { width: u32, height: u32, } fn main() { let rect1 = Rectangle { width: 30, height: 50 }; println!("The area is {}.", area(&rect1)); } fn area(rectangle: &Rectangle) -> u32 { rectangle.width * rectangle.height } ``` ---- ### Rectangleのprintln!(1/2) ```rust struct Rectangle { width: u32, height: u32, } fn main() { let rect1 = Rectangle { width: 30, height: 50 }; println!("rect1 is {}", rect1); } ``` これはエラー(標準的なRectangle->Stringが無い) ---- ### Rectangleのprintln!(2/2) ```rust #[derive(Debug)] struct Rectangle { width: u32, height: u32, } fn main() { let rect1 = Rectangle { width: 30, height: 50 }; println!("rect1 is {:?}", rect1); } ``` * `#[derive(Debug)]`でRectangleにデバッグ宣言 * `{:?}`で構造体をよしなに文字列に変換 --- ## メソッドなど ---- ### Rectangle ```rust #[derive(Debug)] struct Rectangle { width: u32, height: u32, } impl Rectangle { fn area(&self) -> u32 { self.width * self.height } } fn main() { let rect1 = Rectangle { width: 30, height: 50 }; println!("The area is {}.", rect1.area()); } ``` `impl <struct>`内にメソッドを定義 implement: 実装 ---- ### implの書き方 ```rust impl Rectangle { fn area(&self) -> u32 { self.width * self.height } fn perimeter(&self) -> u32 { 2 * self.width + 2 * self.height } } impl Rectangle { fn diagonal(&self) -> f64 { ((self.width * self.width + self.height * self.height) as f64).sqrt() } } ``` 分かれててもok ---- ### 複数のRectangle ```rust impl Rectangle { fn can_hold(&self, other: &Rectangle) -> bool { self.width > other.width && self.height > other.height } } fn main() { let rect1 = Rectangle {width: 30, height: 50 }; let rect2 = Rectangle {width: 10, height: 40 }; let rect3 = Rectangle {width: 60, height: 45 }; println!("Can rect1 hold rect2? {}", rect1.can_hold(&rect2)); // true println!("Can rect1 hold rect3? {}", rect1.can_hold(&rect3)); // false } ``` ---- ### 関連関数 ```rust impl Rectangle { fn square(size: u32) -> Rectangle { Rectangle { width: size, height: size } } } let sq = Rectangle::square(3); ``` として正方形が定義できる. 関連関数はメソッドとは呼ばれない --- ## まとめ・所感 ---- ### まとめ * `struct` * 通常の構造体 * 名前付きタプル * デバッグオプション・省略記法など * `impl` * メソッドの定義 * 関連関数の定義 ---- ### fieldについて * fieldを変更するためには`mut`が必要 (Rustでは当たり前なのだとと思いますが)Juliaでは ```julia mutable struct hoge end struct fuga end ``` によってfieldの変更可能/不能な構造体を分けていたので少し意外に感じました ---- ### モチベーション * 欲しい! * (個人的には)応用先がまだ見えてないので手が遅い感じがあります。 * 数値計算を試そうと思ってたのですが、資料に間に合わず…。 * 原山さんの次々回に期待してます:pray: --- ## 参考資料 https://doc.rust-jp.rs/book/second-edition/ch05-00-structs.html
{"metaMigratedAt":"2023-06-15T11:52:24.425Z","metaMigratedFrom":"YAML","title":"第3回 5章 構造体を使用して関係のあるデータを構造化する","breaks":true,"description":"Rust勉強会第3回のスライド","slideOptions":"{\"theme\":\"white\",\"slideNumber\":\"c/t\",\"center\":false,\"transition\":\"none\",\"keyboard\":true}","contributors":"[{\"id\":\"41421433-16a1-4a57-ac11-6f7b7becb765\",\"add\":9012,\"del\":1253}]"}
    209 views