<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}]"}