diff --git a/tour-of-rust/.gitignore b/tour-of-rust/.gitignore new file mode 100644 index 0000000..94212fa --- /dev/null +++ b/tour-of-rust/.gitignore @@ -0,0 +1,17 @@ +### Generated by gibo (https://github.com/simonwhitaker/gibo) +### https://raw.github.com/github/gitignore/3bb7b4b767f3f8df07e362dfa03c8bd425f16d32/Rust.gitignore + +# Generated by Cargo +# will have compiled files and executables +debug/ +target/ + +# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries +# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html +Cargo.lock + +# These are backup files generated by rustfmt +**/*.rs.bk + +# MSVC Windows builds of rustc generate these, which store debugging information +*.pdb diff --git a/tour-of-rust/Cargo.toml b/tour-of-rust/Cargo.toml new file mode 100644 index 0000000..007b0e6 --- /dev/null +++ b/tour-of-rust/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "tour-of-rust" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/tour-of-rust/README.md b/tour-of-rust/README.md new file mode 100644 index 0000000..038db9b --- /dev/null +++ b/tour-of-rust/README.md @@ -0,0 +1,3 @@ +# Tour of Rust + +https://tourofrust.com diff --git a/tour-of-rust/examples/06_ja.rs b/tour-of-rust/examples/06_ja.rs new file mode 100644 index 0000000..1a65b51 --- /dev/null +++ b/tour-of-rust/examples/06_ja.rs @@ -0,0 +1,9 @@ +fn main() { + let a = 13u8; + let b = 7u32; + let c = a as u32 + b; + println!("{}", c); + + let t = true; + println!("{}", t as u8); +} diff --git a/tour-of-rust/examples/08_ja.rs b/tour-of-rust/examples/08_ja.rs new file mode 100644 index 0000000..d4acd5c --- /dev/null +++ b/tour-of-rust/examples/08_ja.rs @@ -0,0 +1,6 @@ +/// 配列 +fn main() { + let nums: [i32; 3] = [1, 2, 3]; + println!("{:?}", nums); + println!("{}", nums[1]); +} diff --git a/tour-of-rust/examples/100_ja.rs b/tour-of-rust/examples/100_ja.rs new file mode 100644 index 0000000..724f81c --- /dev/null +++ b/tour-of-rust/examples/100_ja.rs @@ -0,0 +1,22 @@ +use std::rc::Rc; + +struct Pie; + +impl Pie { + fn eat(&self) { + println!("tastes better on the heap!") + } +} + +fn main() { + let heap_pie = Rc::new(Pie); + let heap_pie2 = heap_pie.clone(); + let heap_pie3 = heap_pie2.clone(); + + heap_pie3.eat(); + heap_pie2.eat(); + heap_pie.eat(); + + // all reference count smart pointers are dropped now + // the heap data Pie finally deallocates +} diff --git a/tour-of-rust/examples/11_ja.rs b/tour-of-rust/examples/11_ja.rs new file mode 100644 index 0000000..f5c7c86 --- /dev/null +++ b/tour-of-rust/examples/11_ja.rs @@ -0,0 +1,18 @@ +fn make_nothing() -> () { + return (); +} + +// 戻り値は () と推論 +fn make_nothing2() { + // この関数は戻り値が指定されないため () を返す +} + +fn main() { + let a = make_nothing(); + let b = make_nothing2(); + + // 空を表示するのは難しいので、 + // a と b のデバッグ文字列を表示 + println!("a の値: {:?}", a); + println!("b の値: {:?}", b); +} diff --git a/tour-of-rust/examples/18_ja.rs b/tour-of-rust/examples/18_ja.rs new file mode 100644 index 0000000..90d7898 --- /dev/null +++ b/tour-of-rust/examples/18_ja.rs @@ -0,0 +1,25 @@ +fn main() { + let x = 42; + + match x { + 0 => { + println!("found zero"); + } + // 複数の値にマッチ + 1 | 2 => { + println!("found 1 or 2!"); + } + // 範囲にマッチ + 3..=9 => { + println!("found a number 3 to 9 inclusively"); + } + // マッチした数字を変数に束縛 + matched_num @ 10..=100 => { + println!("found {} number between 10 to 100!", matched_num); + } + // どのパターンにもマッチしない場合のデフォルトマッチが必須 + _ => { + println!("found something else!"); + } + } +} diff --git a/tour-of-rust/examples/26_ja.rs b/tour-of-rust/examples/26_ja.rs new file mode 100644 index 0000000..66430d5 --- /dev/null +++ b/tour-of-rust/examples/26_ja.rs @@ -0,0 +1,38 @@ +/// メモリの中でデータを作成する +struct SeaCreature { + animal_type: String, + name: String, + arms: i32, + legs: i32, + weapon: String, +} + +fn main() { + // SeaCreatureのデータはスタックに入ります。 + let ferris = SeaCreature { + // String構造体もスタックに入りますが、 + // ヒープに入るデータの参照アドレスが一つ入ります。 + animal_type: String::from("crab"), + name: String::from("Ferris"), + arms: 2, + legs: 4, + weapon: String::from("claw"), + }; + + let sarah = SeaCreature { + animal_type: String::from("octopus"), + name: String::from("Sarah"), + arms: 8, + legs: 0, + weapon: String::from("none"), + }; + + println!( + "{} is a {}. They have {} arms, {} legs, and a {} weapon", + ferris.name, ferris.animal_type, ferris.arms, ferris.legs, ferris.weapon + ); + println!( + "{} is a {}. They have {} arms, and {} legs. They have no weapon..", + sarah.name, sarah.animal_type, sarah.arms, sarah.legs + ); +} diff --git a/tour-of-rust/examples/30_ja.rs b/tour-of-rust/examples/30_ja.rs new file mode 100644 index 0000000..5945437 --- /dev/null +++ b/tour-of-rust/examples/30_ja.rs @@ -0,0 +1,60 @@ +#![allow(dead_code)] // この行でコンパイラのwaringsメッセージを止めます。 + +enum Species { + Crab, + Octopus, + Fish, + Clam, +} +enum PoisonType { + Acidic, + Painful, + Lethal, +} +enum Size { + Big, + Small, +} +enum Weapon { + Claw(i32, Size), + Poison(PoisonType), + None, +} + +struct SeaCreature { + species: Species, + name: String, + arms: i32, + legs: i32, + weapon: Weapon, +} + +fn main() { + // SeaCreatureのデータはスタックに入ります。 + let ferris = SeaCreature { + // String構造体もスタックに入りますが、 + // ヒープに入るデータの参照アドレスが一つ入ります。 + species: Species::Crab, + name: String::from("Ferris"), + arms: 2, + legs: 4, + weapon: Weapon::Claw(2, Size::Small), + }; + + match ferris.species { + Species::Crab => match ferris.weapon { + Weapon::Claw(num_claws, size) => { + let size_description = match size { + Size::Big => "big", + Size::Small => "small", + }; + println!( + "ferris is a crab with {} {} claws", + num_claws, size_description + ) + } + _ => println!("ferris is a crab with some other weapon"), + }, + _ => println!("ferris is some other animal"), + } +} diff --git a/tour-of-rust/examples/33_ja.rs b/tour-of-rust/examples/33_ja.rs new file mode 100644 index 0000000..c5d6fb0 --- /dev/null +++ b/tour-of-rust/examples/33_ja.rs @@ -0,0 +1,24 @@ +// 部分的に定義された構造体型 +struct BagOfHolding { + item: T, +} + +fn main() { + // 注意: ジェネリック型を使用すると、型はコンパイル時に作成される。 + // ::<> (turbofish) で明示的に型を指定 + let i32_bag = BagOfHolding:: { item: 42 }; + let bool_bag = BagOfHolding:: { item: true }; + + // ジェネリック型でも型推論可能 + let float_bag = BagOfHolding { item: 3.14 }; + + // 注意: 実生活では手提げ袋を手提げ袋に入れないように + let bag_in_bag = BagOfHolding { + item: BagOfHolding { item: "boom!" }, + }; + + println!( + "{} {} {} {}", + i32_bag.item, bool_bag.item, float_bag.item, bag_in_bag.item.item + ); +} diff --git a/tour-of-rust/examples/35_ja.rs b/tour-of-rust/examples/35_ja.rs new file mode 100644 index 0000000..02eb337 --- /dev/null +++ b/tour-of-rust/examples/35_ja.rs @@ -0,0 +1,35 @@ +/// Option + + +// 部分的に定義された構造体型 +struct BagOfHolding { + // パラメータ T を渡すことが可能 + item: Option, +} + +fn main() { + // 注意: i32 が入るバッグに、何も入っていません! + // None からは型が決められないため、型を指定する必要があります。 + let i32_bag = BagOfHolding:: { item: None }; + + if i32_bag.item.is_none() { + println!("バッグには何もない!") + } else { + println!("バッグには何かある!") + } + + let i32_bag = BagOfHolding:: { item: Some(42) }; + + if i32_bag.item.is_some() { + println!("バッグには何かある!") + } else { + println!("バッグには何もない!") + } + + // match は Option をエレガントに分解して、 + // すべてのケースが処理されることを保証できます! + match i32_bag.item { + Some(v) => println!("バッグに {} を発見!", v), + None => println!("何も見付からなかった"), + } +} diff --git a/tour-of-rust/examples/36_ja.rs b/tour-of-rust/examples/36_ja.rs new file mode 100644 index 0000000..1b07e3b --- /dev/null +++ b/tour-of-rust/examples/36_ja.rs @@ -0,0 +1,18 @@ +fn do_something_that_might_fail(i: i32) -> Result { + if i == 42 { + Ok(13.0) + } else { + Err(String::from("正しい値ではありません")) + } +} + +fn main() { + let result = do_something_that_might_fail(12); + + // match は Result をエレガントに分解して、 + // すべてのケースが処理されることを保証できます! + match result { + Ok(v) => println!("発見 {}", v), + Err(e) => println!("Error: {}", e), + } +} diff --git a/tour-of-rust/examples/38_ja.rs b/tour-of-rust/examples/38_ja.rs new file mode 100644 index 0000000..e6bb396 --- /dev/null +++ b/tour-of-rust/examples/38_ja.rs @@ -0,0 +1,14 @@ +fn do_something_that_might_fail(i: i32) -> Result { + if i == 42 { + Ok(13.0) + } else { + Err(String::from("正しい値ではありません")) + } +} + +fn main() -> Result<(), String> { + // コードが簡潔なのに注目! + let v = do_something_that_might_fail(42)?; + println!("発見 {}", v); + Ok(()) +} diff --git a/tour-of-rust/examples/40_ja.rs b/tour-of-rust/examples/40_ja.rs new file mode 100644 index 0000000..7402dd9 --- /dev/null +++ b/tour-of-rust/examples/40_ja.rs @@ -0,0 +1,20 @@ +fn main() { + // 型を明示的に指定 + let mut i32_vec = Vec::::new(); // turbofish <3 + i32_vec.push(1); + i32_vec.push(2); + i32_vec.push(3); + + // もっと賢く、型を自動的に推論 + let mut float_vec = Vec::new(); + float_vec.push(1.3); + float_vec.push(2.3); + float_vec.push(3.4); + + // きれいなマクロ! + let string_vec = vec![String::from("Hello"), String::from("World")]; + + for word in string_vec.iter() { + println!("{}", word); + } +} diff --git a/tour-of-rust/examples/46_ja.rs b/tour-of-rust/examples/46_ja.rs new file mode 100644 index 0000000..c770ceb --- /dev/null +++ b/tour-of-rust/examples/46_ja.rs @@ -0,0 +1,19 @@ +struct Foo { + x: i32, +} + +fn do_something(f: Foo) { + println!("{}", f.x); + // f はここでドロップ +} + +fn main() { + let foo = Foo { x: 42 }; + // foo の所有権は do_something に移動 + do_something(foo); + + // foo は使えなくなる + // borrow of moved value: `foo` + // value borrowed here after move + // println!("{}", foo.x); +} diff --git a/tour-of-rust/examples/49_ja.rs b/tour-of-rust/examples/49_ja.rs new file mode 100644 index 0000000..aec8046 --- /dev/null +++ b/tour-of-rust/examples/49_ja.rs @@ -0,0 +1,32 @@ +/// 参照による所有権の可変な借用 + +struct Foo { + x: i32, +} + +fn do_something(f: Foo) { + println!("{}", f.x); + // f はここでドロップ +} + +fn main() { + let mut foo = Foo { x: 42 }; + let f = &mut foo; + + // 失敗: do_something(foo) はここでエラー + // foo は可変に借用されており移動できないため + + // 失敗: foo.x = 13; はここでエラー + // foo は可変に借用されている間は変更できないため + + f.x = 13; + // f はここから先では使用されないため、ここでドロップ + + println!("{}", foo.x); + + // 可変な借用はドロップされているため変更可能 + foo.x = 7; + + // foo の所有権を関数に移動 + do_something(foo); +} diff --git a/tour-of-rust/examples/53_ja.rs b/tour-of-rust/examples/53_ja.rs new file mode 100644 index 0000000..d05464d --- /dev/null +++ b/tour-of-rust/examples/53_ja.rs @@ -0,0 +1,19 @@ +struct Foo { + x: i32, +} + +// 引数 foo と戻り値はライフタイムを共有 +fn do_something<'a>(foo: &'a Foo) -> &'a i32 { + return &foo.x; +} + +fn main() { + let mut foo = Foo { x: 42 }; + let x = &mut foo.x; + *x = 13; + // x はここでドロップされるため、不変な参照が作成可能 + let y = do_something(&foo); + println!("{}", y); + // y はここでドロップ + // foo はここでドロップ +} diff --git a/tour-of-rust/examples/54_ja.rs b/tour-of-rust/examples/54_ja.rs new file mode 100644 index 0000000..c4c9912 --- /dev/null +++ b/tour-of-rust/examples/54_ja.rs @@ -0,0 +1,22 @@ +struct Foo { + x: i32, +} + +// foo_b と戻り値はライフタイムを共有 +// foo_a のライフタイムは別 +fn do_something<'a, 'b>(foo_a: &'a Foo, foo_b: &'b Foo) -> &'b i32 { + println!("{}", foo_a.x); + println!("{}", foo_b.x); + return &foo_b.x; +} + +fn main() { + let foo_a = Foo { x: 42 }; + let foo_b = Foo { x: 12 }; + let x = do_something(&foo_a, &foo_b); + // ここから先は foo_b のライフタイムしか存在しないため、 + // foo_a はここでドロップ + println!("{}", x); + // x はここでドロップ + // foo_b はここでドロップ +} diff --git a/tour-of-rust/examples/65_ja.rs b/tour-of-rust/examples/65_ja.rs new file mode 100644 index 0000000..d796ccd --- /dev/null +++ b/tour-of-rust/examples/65_ja.rs @@ -0,0 +1,10 @@ +/// 文字列スライス +fn main() { + let a = "hi 🦀"; + println!("{}", a.len()); + let first_word = &a[0..2]; + let second_word = &a[3..7]; + // let half_crab = &a[3..5]; は失敗します。 + // Rust は無効な unicode 文字のスライスを受け付けません。 + println!("{} {}", first_word, second_word); +} diff --git a/tour-of-rust/examples/66_ja.rs b/tour-of-rust/examples/66_ja.rs new file mode 100644 index 0000000..c7d9d36 --- /dev/null +++ b/tour-of-rust/examples/66_ja.rs @@ -0,0 +1,7 @@ +fn main() { + // 文字をcharのベクトルとして集める + let chars = "hi 🦀".chars().collect::>(); + println!("{}", chars.len()); // should be 4 + // chars は 4 バイトなので、u32 に変換することができる + println!("{}", chars[2] as u32); +} diff --git a/tour-of-rust/examples/68_ja.rs b/tour-of-rust/examples/68_ja.rs new file mode 100644 index 0000000..0e9433f --- /dev/null +++ b/tour-of-rust/examples/68_ja.rs @@ -0,0 +1,10 @@ +fn say_it_loud(msg: &str) { + println!("{}!!!", msg.to_string().to_uppercase()); +} + +fn main() { + // say_it_loudは&'static strを&strとして借用することができます + say_it_loud("hello"); + // say_it_loudはStringを&strとして借用することもできます + say_it_loud(&String::from("goodbye")); +} diff --git a/tour-of-rust/examples/69_ja.rs b/tour-of-rust/examples/69_ja.rs new file mode 100644 index 0000000..28675b7 --- /dev/null +++ b/tour-of-rust/examples/69_ja.rs @@ -0,0 +1,7 @@ +fn main() { + let helloworld = vec!["hello", " ", "world", "!"].concat(); + let helloworld = ["hello", " ", "world", "!"].concat(); + let abc = ["a", "b", "c"].join(","); + println!("{}", helloworld); + println!("{}", abc); +} diff --git a/tour-of-rust/examples/71_ja.rs b/tour-of-rust/examples/71_ja.rs new file mode 100644 index 0000000..9a5b28f --- /dev/null +++ b/tour-of-rust/examples/71_ja.rs @@ -0,0 +1,7 @@ +fn main() -> Result<(), std::num::ParseIntError> { + let a = 42; + let a_string = a.to_string(); + let b = a_string.parse::()?; + println!("{} {}", a, b); + Ok(()) +} diff --git a/tour-of-rust/examples/76_ja.rs b/tour-of-rust/examples/76_ja.rs new file mode 100644 index 0000000..34b24ec --- /dev/null +++ b/tour-of-rust/examples/76_ja.rs @@ -0,0 +1,16 @@ +struct SeaCreature { + noise: String, +} + +impl SeaCreature { + fn get_sound(&self) -> &str { + &self.noise + } +} + +fn main() { + let creature = SeaCreature { + noise: String::from("blub"), + }; + println!("{}", creature.get_sound()); +} diff --git a/tour-of-rust/examples/78_ja.rs b/tour-of-rust/examples/78_ja.rs new file mode 100644 index 0000000..b22a083 --- /dev/null +++ b/tour-of-rust/examples/78_ja.rs @@ -0,0 +1,28 @@ +struct SeaCreature { + pub name: String, + noise: String, +} + +impl SeaCreature { + pub fn get_sound(&self) -> &str { + &self.noise + } +} + +trait NoiseMaker { + fn make_noise(&self); +} + +impl NoiseMaker for SeaCreature { + fn make_noise(&self) { + println!("{}", &self.get_sound()); + } +} + +fn main() { + let creature = SeaCreature { + name: String::from("Ferris"), + noise: String::from("blub"), + }; + creature.make_noise(); +} diff --git a/tour-of-rust/examples/81_ja.rs b/tour-of-rust/examples/81_ja.rs new file mode 100644 index 0000000..dcb3bac --- /dev/null +++ b/tour-of-rust/examples/81_ja.rs @@ -0,0 +1,40 @@ +/// 動的ディスパッチと性的ディスパッチ +struct SeaCreature { + pub name: String, + noise: String, +} + +impl SeaCreature { + pub fn get_sound(&self) -> &str { + &self.noise + } +} + +trait NoiseMaker { + fn make_noise(&self); +} + +impl NoiseMaker for SeaCreature { + fn make_noise(&self) { + println!("{}", &self.get_sound()); + } +} + +fn static_make_noise(creature: &SeaCreature) { + // we know the real type + creature.make_noise(); +} + +fn dynamic_make_noise(noise_maker: &dyn NoiseMaker) { + // we don't know the real type + noise_maker.make_noise(); +} + +fn main() { + let creature = SeaCreature { + name: String::from("Ferris"), + noise: String::from("blub"), + }; + static_make_noise(&creature); + dynamic_make_noise(&creature); +} diff --git a/tour-of-rust/examples/84_ja.rs b/tour-of-rust/examples/84_ja.rs new file mode 100644 index 0000000..6a06a91 --- /dev/null +++ b/tour-of-rust/examples/84_ja.rs @@ -0,0 +1,36 @@ +struct SeaCreature { + pub name: String, + noise: String, +} + +impl SeaCreature { + pub fn get_sound(&self) -> &str { + &self.noise + } +} + +trait NoiseMaker { + fn make_noise(&self); +} + +impl NoiseMaker for SeaCreature { + fn make_noise(&self) { + println!("{}", &self.get_sound()); + } +} + +fn generic_make_noise(creature: &T) +where + T: NoiseMaker, +{ + // we know the real type at compile-time + creature.make_noise(); +} + +fn main() { + let creature = SeaCreature { + name: String::from("Ferris"), + noise: String::from("blub"), + }; + generic_make_noise(&creature); +} diff --git a/tour-of-rust/examples/86_ja.rs b/tour-of-rust/examples/86_ja.rs new file mode 100644 index 0000000..de379c9 --- /dev/null +++ b/tour-of-rust/examples/86_ja.rs @@ -0,0 +1,42 @@ +/// ボックス +struct SeaCreature { + pub name: String, + noise: String, +} + +impl SeaCreature { + pub fn get_sound(&self) -> &str { + &self.noise + } +} + +trait NoiseMaker { + fn make_noise(&self); +} + +impl NoiseMaker for SeaCreature { + fn make_noise(&self) { + println!("{}", &self.get_sound()); + } +} + +struct Ocean { + animals: Vec>, +} + +fn main() { + let ferris = SeaCreature { + name: String::from("Ferris"), + noise: String::from("blub"), + }; + let sarah = SeaCreature { + name: String::from("Sarah"), + noise: String::from("swish"), + }; + let ocean = Ocean { + animals: vec![Box::new(ferris), Box::new(sarah)], + }; + for a in ocean.animals.iter() { + a.make_noise(); + } +} diff --git a/tour-of-rust/examples/91_ja.rs b/tour-of-rust/examples/91_ja.rs new file mode 100644 index 0000000..81ced84 --- /dev/null +++ b/tour-of-rust/examples/91_ja.rs @@ -0,0 +1,5 @@ +fn main() { + let a = 42; + let memory_location = &a as *const i32 as usize; + println!("Data is here {}", memory_location); +} diff --git a/tour-of-rust/examples/93_ja.rs b/tour-of-rust/examples/93_ja.rs new file mode 100644 index 0000000..ff6d93c --- /dev/null +++ b/tour-of-rust/examples/93_ja.rs @@ -0,0 +1,7 @@ +fn main() { + let a: i32 = 42; + let ref_ref_ref_a: &&&i32 = &&&a; + let ref_a: &i32 = **ref_ref_ref_a; + let b: i32 = *ref_a; + println!("{}", ref_ref_ref_a) +} diff --git a/tour-of-rust/examples/94_ja.rs b/tour-of-rust/examples/94_ja.rs new file mode 100644 index 0000000..f0203b5 --- /dev/null +++ b/tour-of-rust/examples/94_ja.rs @@ -0,0 +1,9 @@ +struct Foo { + value: i32, +} + +fn main() { + let f = Foo { value: 42 }; + let ref_ref_ref_f = &&&f; + println!("{}", ref_ref_ref_f.value); +} diff --git a/tour-of-rust/examples/95_ja.rs b/tour-of-rust/examples/95_ja.rs new file mode 100644 index 0000000..6b2619d --- /dev/null +++ b/tour-of-rust/examples/95_ja.rs @@ -0,0 +1,27 @@ +use std::ops::{Deref, Drop}; +struct TattleTell { + value: T, +} +impl Deref for TattleTell { + type Target = T; + fn deref(&self) -> &T { + println!("{} was used!", std::any::type_name::()); + &self.value + } +} + +impl Drop for TattleTell { + fn drop(&mut self) { + println!("Dropping"); + } +} + +fn main() { + let foo = TattleTell { + value: "secret message", + }; + // dereference occurs here immediately + // after foo is auto-referenced for the + // function `len` + println!("{}", foo.len()); +} diff --git a/tour-of-rust/examples/96_ja.rs b/tour-of-rust/examples/96_ja.rs new file mode 100644 index 0000000..d3d8435 --- /dev/null +++ b/tour-of-rust/examples/96_ja.rs @@ -0,0 +1,18 @@ +fn main() { + let a: [u8; 4] = [86, 14, 73, 64]; + // this is a raw pointer. Getting the memory address + // of something as a number is totally safe + let pointer_a = &a as *const u8 as usize; + println!("Data memory location: {}", pointer_a); + // Turning our number into a raw pointer to a f32 is + // also safe to do. + let pointer_b = pointer_a as *const f32; + let b = unsafe { + // This is unsafe because we are telling the compiler + // to assume our pointer is a valid f32 and + // dereference it's value into the variable b. + // Rust has no way to verify this assumption is true. + *pointer_b + }; + println!("I swear this is a pie! {}", b); +} diff --git a/tour-of-rust/examples/97_ja.rs b/tour-of-rust/examples/97_ja.rs new file mode 100644 index 0000000..ddda582 --- /dev/null +++ b/tour-of-rust/examples/97_ja.rs @@ -0,0 +1,43 @@ +use std::alloc::{alloc, Layout}; +use std::ops::Deref; + +struct Pie { + secret_recipe: usize, +} + +impl Pie { + fn new() -> Self { + // let's ask for 4 bytes + let layout = Layout::from_size_align(4, 1).unwrap(); + + unsafe { + // allocate and save the memory location as a number + let ptr = alloc(layout) as *mut u8; + // use pointer math and write a few + // u8 values to memory + ptr.write(86); + ptr.add(1).write(14); + ptr.add(2).write(73); + ptr.add(3).write(64); + + Pie { + secret_recipe: ptr as usize, + } + } + } +} +impl Deref for Pie { + type Target = f32; + fn deref(&self) -> &f32 { + // interpret secret_recipe pointer as a f32 raw pointer + let pointer = self.secret_recipe as *const f32; + // dereference it into a return value &f32 + unsafe { &*pointer } + } +} +fn main() { + let p = Pie::new(); + // "make a pie" by dereferencing our + // Pie struct smart pointer + println!("{:?}", *p); +} diff --git a/tour-of-rust/examples/98_ja.rs b/tour-of-rust/examples/98_ja.rs new file mode 100644 index 0000000..dc8ab0a --- /dev/null +++ b/tour-of-rust/examples/98_ja.rs @@ -0,0 +1,12 @@ +struct Pie; + +impl Pie { + fn eat(&self) { + println!("tastes better on the heap!") + } +} + +fn main() { + let heap_pie = Box::new(Pie); + heap_pie.eat(); +} diff --git a/tour-of-rust/examples/99_ja.rs b/tour-of-rust/examples/99_ja.rs new file mode 100644 index 0000000..75ed248 --- /dev/null +++ b/tour-of-rust/examples/99_ja.rs @@ -0,0 +1,27 @@ +use std::error::Error; +use std::fmt::Display; + +struct Pie; + +#[derive(Debug)] +struct NotFreshError; + +impl Display for NotFreshError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "This pie is not fresh!") + } +} + +impl Error for NotFreshError {} + +impl Pie { + fn eat(&self) -> Result<(), Box> { + Err(Box::new(NotFreshError)) + } +} + +fn main() -> Result<(), Box> { + let heap_pie = Box::new(Pie); + heap_pie.eat()?; + Ok(()) +} diff --git a/tour-of-rust/src/main.rs b/tour-of-rust/src/main.rs new file mode 100644 index 0000000..e7a11a9 --- /dev/null +++ b/tour-of-rust/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +}