筆者が、Rust By Exampleを写経したり、Activityを実行したりした記録の2記事目です
この記事のソースコード、記載は正しいかわかりませんし、効率的かどうかもわかりません
ご参考まで
Enums
ソースコード
ソースコード
enum WebEvent {
PageLoad,
PageUnLOad,
KeyPress(char),
Paste(String),
Click { x: i64, y: i64 },
}
fn inspect(event: WebEvent) {
match event {
WebEvent::PageLoad => println!("page loaded"),
WebEvent::PageUnLOad => println!("page unloaded"),
WebEvent::KeyPress(c) => println!("pressed '{}'", c),
WebEvent::Paste(s) => println!("pasted \"{}\"", s),
WebEvent::Click { x, y } => println!("clicked at x={}, y={}", x, y),
}
}
enum VeryVerboseEnumOfThingsToDoWIthNumbers {
Add,
Substruct,
}
type Operations = VeryVerboseEnumOfThingsToDoWIthNumbers;
impl Operations {
fn run(&self, x: i32, y: i32) -> i32 {
match self {
Self::Add => x + y,
Self::Substruct => x - y,
}
}
}
fn main() {
let pressed = WebEvent::KeyPress('x');
let pasted = WebEvent::Paste("my text".to_owned());
let click = WebEvent::Click{ x: 20, y: 80 };
let load = WebEvent::PageLoad;
let unload = WebEvent::PageUnLOad;
inspect(pressed);
inspect(pasted);
inspect(click);
inspect(load);
inspect(unload);
let add = Operations::Add;
let sub = Operations::Substruct;
println!("Add result is {}", add.run(5,5));
println!("Sub result is {}", sub.run(5,5));
}
出力結果
pressed 'x'
pasted "my text"
clicked at x=20, y=80
page loaded
page unloaded
Add result is 10
Sub result is 0
Try
所有権の再確認
- let pasted = WebEvent::Paste("my text".to_owned());
+ let pasted = WebEvent::Paste("my text");
error[E0308]: mismatched types
--> src\main.rs:37:34
|
37 | let pasted = WebEvent::Paste("my text");
| --------------- ^^^^^^^^^- help: try using a conversion method: `.to_string()`
| | |
| | expected `String`, found `&str`
| arguments to this enum variant are incorrect
|
note: tuple variant defined here
--> src\main.rs:5:5
|
5 | Paste(String),
| ^^^^^
For more information about this error, try `rustc --explain E0308`.
to_owned
はそもそも何か?というと、
std::borrow::ToOwned
トレイトのメソッドで、説明は以下の通り
Creates owned data from borrowed data, usually by cloning.
to_string
は、std::string::ToString
トレイトのメソッドで、
Converts the given value to a String
とのことです
この辺りの処理の使い分けや、似ている機能だけど、どういう意味の違いがあるかを調べていきたいですね
use
ソースコード
ソースコード
enum Stage {
Beginner,
Advanced,
}
enum Role {
Student,
Teacher,
}
impl Stage {
fn my_match(&self) {
match self {
Stage::Beginner => println!("Beginners are starting ther learning journey!"),
Stage::Advanced => println!("Advanced learners are mastering their subjects!"),
}
}
}
impl Role {
fn my_match(&self) {
match self {
Role::Student => println!("Students are acquiring knowledge!"),
Role::Teacher => println!("Teachers are spreading knowledge!"),
}
}
}
fn main() {
use crate::Role::*;
use crate::Stage::{Advanced, Beginner};
let stage = Beginner;
let stage2 = Advanced;
let role = Student;
let role2 = Teacher;
stage.my_match();
stage2.my_match();
role.my_match();
role2.my_match();
}
出力結果
Beginners are starting ther learning journey!
Advanced learners are mastering their subjects!
Students are acquiring knowledge!
Teachers are spreading knowledge!
C-like
列挙体はC言語っぽくも書ける
ソースコード
ソースコード
enum Number {
Zero,
One,
Two,
}
enum Color {
Red = 0xff0000,
Green = 0x00ff00,
Blue = 0x0000ff,
}
fn main() {
println!("zero is {}", Number::Zero as i32);
println!("one is {}", Number::One as i32);
println!("two is {}", Number::Two as i32);
println!("roses are #{:06x}", Color::Red as i32);
println!("violets are #{:06x}", Color::Blue as i32);
println!("leafs are #{:06x}", Color::Green as i32);
}
出力結果
zero is 0
one is 1
two is 2
roses are #ff0000
violets are #0000ff
leafs are #00ff00
Testcase: linked-list
ソースコード
ソースコード
use crate::List::*;
enum List {
Cons(u32, Box<List>),
Nil,
}
impl List {
fn new() -> List {
Nil
}
fn prepend(self, el: u32) -> List {
Cons(el, Box::new(self))
}
fn len(&self) -> u32 {
match *self {
Cons(_, ref tail) => 1 + tail.len(),
Nil => 0
}
}
fn stringify(&self) -> String {
match *self {
Cons(head, ref tail) => {
format!("{}, {}", head, tail.stringify())
},
Nil => format!("Nil"),
}
}
}
fn main() {
let mut list = List::new();
list = list.prepend(1);
list = list.prepend(2);
list = list.prepend(3);
println!("linked list has length: {}", list.len());
println!("{}", list.stringify());
}
出力結果
linked list has length: 3
3, 2, 1, Nil
Try
Boxとはなんぞやと思って調べたところ、Rustではすべての値がデフォルトでスタックに割り当てられますが、
Boxを作成することで、値を ボックス化 、すなわちヒープ上に割り当てることができます。ボックスとは正確にはヒープ上におかれたTの値へのスマートポインタです。ボックスがスコープを抜けると、デストラクタが呼ばれて内包するオブジェクトが破棄され、ヒープメモリが解放されます。
とのことです
スタックとかヒープとかは苦手なので、まだ理解できていないのですが、ポインタをスタックに積み、そのポインタが指す領域をヒープに配置するということかな?
ポインタをスタックに積むようにすることで、コンパイル時にメモリの大きさを決定できて、間接的に、ポインタが指す領域は実行時にメモリの大きさを決定できるようになる?
以下のページが包括的な情報です
ここら辺は別途勉強したいと思います
Enums
ソースコード
ソースコード
static LANGUAGE: &str = "Rust";
const THRESHOLD: i32 = 10;
fn is_big(n: i32) -> bool {
n > THRESHOLD
}
fn main() {
let n = 16;
println!("This is {}", LANGUAGE);
println!("The threshold is {}", THRESHOLD);
println!("{} is {}", n, if is_big(n) { "big" } else { "small" });
//THRESHOLD = 5;
}
出力結果
This is Rust
The threshold is 10
16 is big
Try
- //THRESHOLD = 5;
+ THRESHOLD = 5;
constantsな値は左辺に置けない仕様
error[E0070]: invalid left-hand side of assignment
--> src\main.rs:15:15
|
15 | THRESHOLD = 5;
| --------- ^
| |
| cannot assign to this expression
For more information about this error, try `rustc --explain E0070`.
後書き
難しい要素も増えてきました
要勉強なところもあるため、別途勉強していきたいと思います