├── .gitignore ├── Chapter 1 ├── Codes │ ├── Welcome │ │ ├── Welcome.rsproj │ │ └── src │ │ │ └── main.rs │ └── WelcomeC │ │ ├── Cargo.toml │ │ ├── WelcomeC.rsproj │ │ └── src │ │ └── main.rs └── Exercises │ ├── Name │ ├── Name.rsproj │ └── src │ │ └── main.rs │ └── SmallestProgram │ ├── SmallestProgram.rsproj │ └── src │ └── main.rs ├── Chapter 2 ├── Codes │ ├── Alias │ │ ├── Alias.rsproj │ │ └── src │ │ │ └── main.rs │ ├── Bindings │ │ ├── Bindings.rsproj │ │ └── src │ │ │ └── main.rs │ ├── Comments │ │ ├── Comments.rsproj │ │ └── src │ │ │ └── main.rs │ ├── Constants1 │ │ ├── Constants1.rsproj │ │ └── src │ │ │ └── main.rs │ ├── Constants2 │ │ ├── Constants2.rsproj │ │ └── src │ │ │ └── main.rs │ ├── Expressions │ │ ├── Expressions.rsproj │ │ └── src │ │ │ └── main.rs │ ├── MutableConstant │ │ ├── MutableConstant.rsproj │ │ └── src │ │ │ └── main.rs │ ├── References │ │ ├── References.rsproj │ │ └── src │ │ │ └── main.rs │ ├── Scope │ │ ├── Scope.rsproj │ │ └── src │ │ │ └── main.rs │ ├── TypeConversions │ │ ├── TypeConversions.rsproj │ │ └── src │ │ │ └── main.rs │ ├── TypeErrors │ │ ├── TypeErrors.rsproj │ │ └── src │ │ │ └── main.rs │ └── Types2 │ │ ├── Types2.rsproj │ │ └── src │ │ └── main.rs └── Exercises │ ├── ChangeConstant │ ├── ChangeConstant.rsproj │ └── src │ │ └── main.rs │ ├── CompoundLet │ ├── CompoundLet.rsproj │ └── src │ │ └── main.rs │ └── Formatting │ ├── Formatting.rsproj │ └── src │ └── main.rs ├── Chapter 3 ├── Codes │ ├── AttributesCfg │ │ ├── AttributesCfg.rsproj │ │ └── src │ │ │ └── main.rs │ ├── AttributesTesting │ │ ├── AttributesTesting.rsproj │ │ └── src │ │ │ └── main.rs │ ├── ExDoc │ │ ├── ExDoc.rsproj │ │ └── src │ │ │ └── main.rs │ ├── Functions │ │ ├── Functions.rsproj │ │ └── src │ │ │ └── main.rs │ ├── IfElse │ │ ├── IfElse.rsproj │ │ └── src │ │ │ └── main.rs │ ├── IterStep │ │ ├── IterStep.rsproj │ │ └── src │ │ │ └── main.rs │ ├── Loops │ │ ├── Loops.rsproj │ │ └── src │ │ │ └── main.rs │ ├── MyLib │ │ ├── Cargo.toml │ │ ├── MyLib.rsproj │ │ └── src │ │ │ └── main.rs │ └── Random │ │ ├── Cargo.toml │ │ ├── Random.rsproj │ │ └── src │ │ └── main.rs └── Exercises │ ├── Absolute │ ├── Absolute.rsproj │ └── src │ │ └── main.rs │ ├── IfReturn │ ├── IfReturn.rsproj │ └── src │ │ └── main.rs │ └── IfTest │ ├── IfTest.rsproj │ └── src │ └── main.rs ├── Chapter 4 ├── Codes │ ├── Arrays │ │ ├── Arrays.rsproj │ │ └── src │ │ │ └── main.rs │ ├── Enums │ │ ├── Enums.rsproj │ │ └── src │ │ │ └── main.rs │ ├── Input │ │ ├── Input.rsproj │ │ └── src │ │ │ └── main.rs │ ├── PatternMatch │ │ ├── PatternMatch.rsproj │ │ └── src │ │ │ └── main.rs │ ├── PatternMatch2 │ │ ├── PatternMatch2.rsproj │ │ └── src │ │ │ └── main.rs │ ├── Strings │ │ ├── Strings.rsproj │ │ └── src │ │ │ └── main.rs │ ├── Structs │ │ ├── Structs.rsproj │ │ └── src │ │ │ └── main.rs │ └── Tuples │ │ ├── Tuples.rsproj │ │ └── src │ │ └── main.rs └── Exercises │ ├── CharsString │ ├── CharsString.rsproj │ └── src │ │ └── main.rs │ ├── Monster │ ├── Monster.rsproj │ └── src │ │ └── main.rs │ ├── PatternMatch │ ├── PatternMatch.rsproj │ └── src │ │ └── main.rs │ └── TuplesEx │ ├── TuplesEx.rsproj │ └── src │ └── main.rs ├── Chapter 5 ├── Codes │ ├── AdaptersConsumers │ │ ├── AdaptersConsumers.rsproj │ │ └── src │ │ │ └── main.rs │ ├── Errors │ │ ├── Errors.rsproj │ │ └── src │ │ │ └── main.rs │ ├── Generics │ │ ├── Generics.rsproj │ │ └── src │ │ │ └── main.rs │ ├── HigherFunctions │ │ ├── HigherFunctions.rsproj │ │ └── src │ │ │ └── main.rs │ ├── Iterators │ │ ├── Iterators.rsproj │ │ └── src │ │ │ └── main.rs │ ├── Methods │ │ ├── Methods.rsproj │ │ └── src │ │ │ └── main.rs │ ├── TraitConstraints │ │ ├── Cargo.toml │ │ ├── TraitConstraints.rsproj │ │ └── src │ │ │ └── main.rs │ └── Traits │ │ ├── Traits.rsproj │ │ └── src │ │ └── main.rs └── Exercises │ ├── Complex │ ├── Complex.rsproj │ └── src │ │ └── main.rs │ ├── DrawTrait │ ├── DrawTrait.rsproj │ └── src │ │ └── main.rs │ ├── Fold │ ├── Fold.rsproj │ └── src │ │ └── main.rs │ └── RangeNext │ ├── RangeNext.rsproj │ └── src │ └── main.rs ├── Chapter 6 ├── Codes │ ├── Boxes1 │ │ ├── Boxes1.rsproj │ │ └── src │ │ │ └── main.rs │ ├── Boxes2 │ │ ├── Boxes2.rsproj │ │ └── src │ │ │ └── main.rs │ ├── Errors │ │ ├── Errors.rsproj │ │ └── src │ │ │ └── main.rs │ ├── Lifetimes │ │ ├── Lifetimes.rsproj │ │ └── src │ │ │ └── main.rs │ ├── Ownership1 │ │ ├── Ownership1.rsproj │ │ └── src │ │ │ └── main.rs │ ├── Ownership2 │ │ ├── Ownership2.rsproj │ │ └── src │ │ │ └── main.rs │ ├── Ref │ │ ├── Ref.rsproj │ │ └── src │ │ │ └── main.rs │ ├── RefCount │ │ ├── RefCount.rsproj │ │ └── src │ │ │ └── main.rs │ ├── RefCountNotgood │ │ ├── RefCountNotgood.rsproj │ │ └── src │ │ │ └── main.rs │ └── References │ │ ├── References.rsproj │ │ └── src │ │ └── main.rs └── Exercises │ ├── DanglingPointer │ ├── DanglingPointer.rsproj │ └── src │ │ └── main.rs │ ├── GrowTentacle │ ├── GrowTentacle.rsproj │ └── src │ │ └── main.rs │ └── Ownership3 │ ├── Ownership3.rsproj │ └── src │ └── main.rs ├── Chapter 7 ├── Codes │ ├── Cube │ │ ├── Cargo.toml │ │ ├── Cube.rsproj │ │ ├── src │ │ │ ├── lib.rs │ │ │ ├── main.rs │ │ │ └── test.rs │ │ └── tests │ │ │ └── lib.rs │ ├── ImportModules │ │ ├── ImportModules.rsproj │ │ └── src │ │ │ ├── main.rs │ │ │ ├── modul1 │ │ │ └── mod.rs │ │ │ └── modul2.rs │ ├── Macros │ │ ├── Macros.rsproj │ │ └── src │ │ │ └── main.rs │ ├── Modules │ │ ├── Modules.rsproj │ │ └── src │ │ │ └── main.rs │ ├── Monsters │ │ ├── Cargo.toml │ │ ├── Monsters.rsproj │ │ └── src │ │ │ ├── lib.rs │ │ │ └── main.rs │ └── Structs │ │ ├── Structs.rsproj │ │ └── src │ │ └── main.rs └── Exercises │ ├── MacroEx │ ├── MacroEx.rsproj │ └── src │ │ └── main.rs │ └── PrivStruct │ ├── PrivStruct.rsproj │ └── src │ └── main.rs ├── Chapter 8 ├── Codes │ ├── Channels │ │ ├── Channels.rsproj │ │ └── src │ │ │ └── main.rs │ ├── Channels2 │ │ ├── Channels2.rsproj │ │ └── src │ │ │ └── main.rs │ ├── MakeChannel │ │ ├── MakeChannel.rsproj │ │ └── src │ │ │ └── main.rs │ ├── ManyThreads │ │ ├── ManyThreads.rsproj │ │ └── src │ │ │ └── main.rs │ ├── ManyThreads2 │ │ ├── Cargo.toml │ │ ├── ManyThreads2.rsproj │ │ └── src │ │ │ └── main.rs │ ├── NotShared │ │ ├── NotShared.rsproj │ │ └── src │ │ │ └── main.rs │ ├── PanicThread │ │ ├── PanicThread.rsproj │ │ └── src │ │ │ └── main.rs │ ├── SyncChannel │ │ ├── SyncChannel.rsproj │ │ └── src │ │ │ └── main.rs │ ├── ThreadSafe │ │ ├── ThreadSafe.rsproj │ │ └── src │ │ │ └── main.rs │ └── ThreadSpawn │ │ ├── ThreadSpawn.rsproj │ │ └── src │ │ └── main.rs └── Exercises │ └── SharedChannel │ ├── SharedChannel.rsproj │ └── src │ └── main.rs ├── Chapter 9 └── Codes │ ├── Arguments │ ├── Arguments.rsproj │ └── src │ │ └── main.rs │ ├── Asm │ ├── Asm.rsproj │ └── src │ │ └── main.rs │ ├── CallingCLibrary │ ├── CallingCLibrary.rsproj │ └── src │ │ └── main.rs │ ├── CallingLibc │ ├── CallingLibc.rsproj │ └── src │ │ └── main.rs │ ├── RawPointers │ ├── RawPointers.rsproj │ └── src │ │ └── main.rs │ └── Unsafe │ ├── Unsafe.rsproj │ └── src │ └── main.rs ├── LICENSE ├── README.md └── RustEssentials.sln /Chapter 1/Codes/Welcome/Welcome.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | fe9583e6-2a3b-4819-b212-d84f476e81d4 7 | exe 8 | Welcome 9 | Welcome 10 | Welcome 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 1/Codes/Welcome/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | println!("Welcome to the Game!"); 3 | } -------------------------------------------------------------------------------- /Chapter 1/Codes/WelcomeC/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "WelcomeC" 3 | version = "0.1.0" 4 | authors = ["Chris Ohk "] 5 | 6 | [dependencies] 7 | -------------------------------------------------------------------------------- /Chapter 1/Codes/WelcomeC/WelcomeC.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | 0912f6f6-f29f-4313-87f0-39879cea1797 7 | exe 8 | WelcomeC 9 | WelcomeC 10 | WelcomeC 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 1/Codes/WelcomeC/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | println!("Hello, world!"); 3 | } -------------------------------------------------------------------------------- /Chapter 1/Exercises/Name/Name.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | e111587b-f26c-4631-bb80-d2625c2fa872 7 | exe 8 | Name 9 | Name 10 | Name 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 1/Exercises/Name/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | println!("My name is Chris Ohk"); 3 | } -------------------------------------------------------------------------------- /Chapter 1/Exercises/SmallestProgram/SmallestProgram.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | bbcf1f4a-b39d-477a-831b-f8f7aaabdb8d 7 | exe 8 | SmallestProgram 9 | SmallestProgram 10 | SmallestProgram 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 1/Exercises/SmallestProgram/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | 3 | } -------------------------------------------------------------------------------- /Chapter 2/Codes/Alias/Alias.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | 6ec5e9de-de93-434a-8ae0-560b7d4f80e0 7 | exe 8 | Alias 9 | Alias 10 | Alias 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 2/Codes/Alias/src/main.rs: -------------------------------------------------------------------------------- 1 | type MagicPower = u16; 2 | 3 | fn main() { 4 | let run: MagicPower = 7800; 5 | } -------------------------------------------------------------------------------- /Chapter 2/Codes/Bindings/Bindings.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | aa8cca58-71a9-4f98-82a6-b8532691c849 7 | exe 8 | Bindings 9 | Bindings 10 | Bindings 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 2/Codes/Bindings/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let energy = 5; // value 5 is bound to variable energy 3 | // splitting declaration and initialization: 4 | // let _energy = 5; // no warning unused variable 5 | // let energy = 5u; // energy is now an unsigned integer 6 | let copy_energy = energy; 7 | println!("Your energy is {}", energy); 8 | let level_title = "Level 1"; 9 | let dead = false; 10 | let magic_number = 3.14f32; 11 | // an _ can be used to separate the digits from the type to improve readability: 12 | // let magic_number = 3.14_f32; 13 | let empty = (); // the value of the unit type () 14 | 15 | // changing values: 16 | // energy = 25; // error: re-assignment of immutable variable `energy` 17 | let mut fuel = 34; 18 | fuel = 60; 19 | 20 | let n; // error: unable to infer enough type information about `_`; type annotations required 21 | // println!("n is: {}", n); // error: use of possibly uninitialized variable 22 | n = -2; 23 | let n: i32; 24 | // let n: i32 = -2; // n is a binding of type i32 and the value -2 25 | let x = 42u8; 26 | let magic_number = 3.14f64; 27 | } -------------------------------------------------------------------------------- /Chapter 2/Codes/Comments/Comments.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | 9e3c286e-cb81-4825-a946-49f4f5a14762 7 | exe 8 | Comments 9 | Comments 10 | Comments 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 2/Codes/Comments/src/main.rs: -------------------------------------------------------------------------------- 1 | /// Start of the Game 2 | fn main() { 3 | // Here starts the execution of the Game. 4 | // We begin with printing a welcome message: 5 | println!("Welcome to the Game!"); 6 | } -------------------------------------------------------------------------------- /Chapter 2/Codes/Constants1/Constants1.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | 5725c4e6-387c-44e0-9039-aa79602f5742 7 | exe 8 | Constants1 9 | Constants1 10 | Constants1 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 2/Codes/Constants1/src/main.rs: -------------------------------------------------------------------------------- 1 | use std::f32::consts; 2 | 3 | static MAX_HEALTH: i32 = 100; 4 | static GAME_NAME: &'static str = "Monster Attack"; 5 | 6 | fn main() { 7 | const PI: f32 = 3.14; 8 | // use the PI value from the standard library: 9 | println!("{}", PI); 10 | println!("{}", consts::PI); 11 | } 12 | // 3.14 13 | // 3.141593 -------------------------------------------------------------------------------- /Chapter 2/Codes/Constants2/Constants2.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | 15897e56-ad84-4853-ba9b-891bf202d369 7 | exe 8 | Constants2 9 | Constants2 10 | Constants2 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 2/Codes/Constants2/src/main.rs: -------------------------------------------------------------------------------- 1 | static MAX_HEALTH: i32 = 100; 2 | static GAME_NAME: &'static str = "Monster Attack"; 3 | 4 | fn main() { 5 | const PI: f32 = 3.14; 6 | 7 | println!("The Game you are playing is called {}.", GAME_NAME); 8 | println!("You start with {} health points.", MAX_HEALTH); 9 | println!("In the Game {0} you start with {1} % health, yes you read it correctly: {1} points!", 10 | GAME_NAME, MAX_HEALTH); 11 | println!("You have {points} % health", points=70); 12 | 13 | // formatting: 14 | println!("MAX_HEALTH is {:x} in hexadecimal", MAX_HEALTH); 15 | println!("MAX_HEALTH is {:b} in binary", MAX_HEALTH); 16 | 17 | println!("pi is {:e} in floating point notation", PI); 18 | } 19 | // The Game you are playing is called Monster Attack. 20 | // You start with 100 health points. 21 | // In the Game Monster Attack you start with 100 % health, yes you heard it correct: 100 points! 22 | // You have 70 % health 23 | // MAX_HEALTH is 64 in hexadecimal 24 | // MAX_HEALTH is 1100100 in binary 25 | // pi is 3.14e0 in floating point notation -------------------------------------------------------------------------------- /Chapter 2/Codes/Expressions/Expressions.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | 3143e9ad-3df9-4a59-a557-1ac6e0fdc7de 7 | exe 8 | Expressions 9 | Expressions 10 | Expressions 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 2/Codes/Expressions/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | // declarative statements: 3 | let a = 2; 4 | let b = 5; 5 | let n = a + b; // n binds to 7 6 | let m: i8; 7 | 8 | m = 42; // expression that returns the unit value () 9 | 10 | // let p = q = 3; // unresolved name q 11 | 12 | // chained let bindings: 13 | let mut n = 0; 14 | let mut m = 1; 15 | let t = m; m = n; n = t; 16 | println!("{} {} {}", n, m, t); // 1 0 1 17 | 18 | // expression that returns a + b 19 | let n1 = { 20 | let a = 2; 21 | let b = 5; 22 | a + b // <-- no semicolon! 23 | }; 24 | println!("n1 is: {}", n1); // n1 is 7 25 | 26 | // expression that returns the unit value () 27 | let n2 = { 28 | let a = 2; 29 | let b = 5; 30 | a + b; 31 | }; 32 | println!("n2 is: {:?}", n2); // n2 is () 33 | } 34 | // n1 is: 7 35 | // n2 is: () -------------------------------------------------------------------------------- /Chapter 2/Codes/MutableConstant/MutableConstant.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | 062a4111-03c0-46d2-8ba1-cb4f4488e55f 7 | exe 8 | MutableConstant 9 | MutableConstant 10 | MutableConstant 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 2/Codes/MutableConstant/src/main.rs: -------------------------------------------------------------------------------- 1 | static mut globvar: i32 = 42; 2 | 3 | fn main() { 4 | 5 | // error: use of mutable static requires unsafe function or block [E0133] 6 | unsafe { // because it is dangerous to change a global variable! 7 | globvar = 0; 8 | println!("My variable global constant: {}", globvar); 9 | } 10 | 11 | } 12 | // My variable global constant: 0 -------------------------------------------------------------------------------- /Chapter 2/Codes/References/References.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | 12a0be32-3497-4d83-94ba-b4b9836ff405 7 | exe 8 | References 9 | References 10 | References 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 2/Codes/References/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let health = 32; 3 | let mut game = "Space Invaders"; 4 | println!("address of health-value: {:p}", &health); // prints 0x23fba4 5 | println!("address of game-value: {:p}", &game); // prints 0x23fb90 6 | println!("game-value: {}", game); // prints "Space Invaders" 7 | println!("game: {}", &game); // prints "Space Invaders" 8 | 9 | let game2 = &game; 10 | println!("{:p}", game2); // prints 0x23fb90 11 | println!("{}", *game2); // prints "Space Invaders" 12 | println!("{}", game2); // prints "Space Invaders" 13 | 14 | let x: &i64; 15 | // println!("{:?}", x); // error: use of possibly uninitialized variable: `x` 16 | 17 | // health = 33; // error: re-assignment of immutable variable `health` 18 | let y = &health; 19 | // now *y is the value 32 20 | 21 | // references to an immutable variable: 22 | let tricks = 10; 23 | // let reftricks = &mut tricks; // error: cannot borrow immutable local variable `tricks` as mutable 24 | 25 | // references to a mutable variable: 26 | let mut score = 0; 27 | let score2 = &score; 28 | // *score2 = 5; // cannot assign to immutable borrowed content *score2 29 | 30 | let mut score = 0; 31 | let score3 = &mut score; 32 | *score3 = 5; 33 | 34 | // let score4 = &mut score; 35 | // error: cannot borrow `score` as mutable more than once at a time 36 | 37 | // boxing values onto the heap: 38 | let x = Box::new(5i32); 39 | // error: box expression syntax is experimental; you can call `Box::new` instead. 40 | // let x = box 5i32; 41 | 42 | } 43 | // address of health-value: 0x23fb04 44 | // address of game-value: 0x23faf0 45 | // game-value: Space Invaders 46 | // game: Space Invaders 47 | // 0x23faf0 48 | // Space Invaders 49 | // Space Invaders -------------------------------------------------------------------------------- /Chapter 2/Codes/Scope/Scope.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | a574e86e-da45-4672-8c73-4f8bb921d37f 7 | exe 8 | Scope 9 | Scope 10 | Scope 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 2/Codes/Scope/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let outer = 42; 3 | { // start code block 4 | // This variable only exists in this block 5 | let inner = 3.14; 6 | println!("block variable: {}", inner); 7 | let outer = 99; // shadows the first outer variable 8 | println!("block variable outer: {}", outer); 9 | } // end of code block 10 | // println!("out of block: {}", inner); // error: unresolved name inner 11 | println!("outer variable: {}", outer); 12 | } 13 | // block variable: 3.14 14 | // block variable outer: 99 15 | // outer variable: 42 -------------------------------------------------------------------------------- /Chapter 2/Codes/TypeConversions/TypeConversions.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | 0ffc726c-593c-4ce0-b5aa-03ac6352de50 7 | exe 8 | TypeConversions 9 | TypeConversions 10 | TypeConversions 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 2/Codes/TypeConversions/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let points = 10i32; 3 | let mut saved_points: u32 = 0; 4 | // saved_points = points; // error 5 | // error: mismatched types: expected `u32`, found `i32` (expected u32, found i32) 6 | saved_points = points as u32; 7 | 8 | let f2 = 3.14; 9 | // truncation occurs here: 10 | saved_points = f2 as u32; 11 | println! ("{}", saved_points); // 3 12 | 13 | let mag = "Gandalf"; 14 | // saved_points = mag as u32; // error: non-scalar cast: `&str` as `u32` 15 | } -------------------------------------------------------------------------------- /Chapter 2/Codes/TypeErrors/TypeErrors.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | 1fcc2669-7237-4320-9994-f0b2113f5368 7 | exe 8 | TypeErrors 9 | TypeErrors 10 | TypeErrors 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 2/Codes/TypeErrors/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let score: i32 = 100; 3 | // score = "YOU WON!"; 4 | // error: mismatched types: expected `i32`, found `&'static str` 5 | // (expected i32, found &-ptr) 6 | let score = "YOU WON!"; 7 | 8 | let player1 = "Rob"; 9 | let player2 = "Jane"; 10 | // let player3 = player1 + player2; 11 | // error: binary operation `+` cannot be applied to type `&str` 12 | let player3 = player1.to_string() + player2; 13 | println!("{}", player3); 14 | let player3 = format!("{}{}", player1, player2); 15 | println!("{}", player3); 16 | } 17 | // RobJane 18 | // RobJane -------------------------------------------------------------------------------- /Chapter 2/Codes/Types2/Types2.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | 50b70e4e-8e04-4815-be23-ca9bd4e659d7 7 | exe 8 | Types2 9 | Types2 10 | Types2 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 2/Codes/Types2/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let x = 42u8; 3 | let magic_number = 3.14f64; 4 | } -------------------------------------------------------------------------------- /Chapter 2/Exercises/ChangeConstant/ChangeConstant.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | 9d14e973-5202-46dc-b36c-e82711422f55 7 | exe 8 | ChangeConstant 9 | ChangeConstant 10 | ChangeConstant 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 2/Exercises/ChangeConstant/src/main.rs: -------------------------------------------------------------------------------- 1 | static MAXHEALTH: i32 = 100; 2 | static GAMENAME: &'static str = "Monster Attack"; 3 | 4 | fn main() { 5 | // MAXHEALTH = 99; // error: cannot assign to immutable static item 6 | } 7 | /*change_constant.rs:5:2: 5:16 error: cannot assign to immutable static item 8 | change_constant.rs:5 MAXHEALTH = 99; 9 | error: aborting due to previous error 10 | [Finished in 0.8s]*/ 11 | -------------------------------------------------------------------------------- /Chapter 2/Exercises/CompoundLet/CompoundLet.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | f52d8229-8d4b-4bfa-b3f9-c33f73c549c4 7 | exe 8 | CompoundLet 9 | CompoundLet 10 | CompoundLet 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 2/Exercises/CompoundLet/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let mut a = 5; 3 | let mut b = 6; 4 | let n = 7; 5 | let a = b = n; 6 | println!("{:?}{:?}{:?}", a, b, n); 7 | } -------------------------------------------------------------------------------- /Chapter 2/Exercises/Formatting/Formatting.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | 302bde3f-2c94-44e9-87ac-02d7c332a0f4 7 | exe 8 | Formatting 9 | Formatting 10 | Formatting 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 2/Exercises/Formatting/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let dec = 3.2f32; 3 | // should be printed out as +003.20 4 | println!("{}", dec); // 3.2 5 | println!("{:+007.2}", dec); // +003.20 6 | // explanation: 7 | // +00 = literal text 8 | // 7 = total character width of output 9 | // .2 = 2 digits after decimal point 10 | } -------------------------------------------------------------------------------- /Chapter 3/Codes/AttributesCfg/AttributesCfg.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | 6e2505fe-d51b-4b57-a839-96d8cfbd8afb 7 | exe 8 | AttributesCfg 9 | AttributesCfg 10 | AttributesCfg 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 3/Codes/AttributesCfg/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | on_windows(); 3 | } 4 | 5 | #[cfg(target_os = "windows")] 6 | fn on_windows() { 7 | println!("This machine has Windows as its OS.") 8 | } 9 | // This machine has Windows as its OS. -------------------------------------------------------------------------------- /Chapter 3/Codes/AttributesTesting/AttributesTesting.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | 63e71c59-69c0-4d43-87a8-67690cc26ded 7 | exe 8 | AttributesTesting 9 | AttributesTesting 10 | AttributesTesting 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 3/Codes/AttributesTesting/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | println!("No tests are compiled, compile with rustc --test!"); 3 | } 4 | 5 | #[test] 6 | fn arithmetic() { 7 | if 2 + 3 == 5 { 8 | println!("You can calculate!"); 9 | } 10 | if 2 + 3 == 6 { // this test passes as wel! 11 | println!("You cannot calculate!"); 12 | } 13 | // good tests: 14 | assert_eq!(5, 2 + 3); 15 | assert!(2 + 3 == 5); 16 | } 17 | 18 | #[test] 19 | fn badtest() { 20 | assert_eq!(6, 2 + 3); 21 | } -------------------------------------------------------------------------------- /Chapter 3/Codes/ExDoc/ExDoc.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | 657d7581-79a9-4d85-a912-6a1094a37a34 7 | exe 8 | ExDoc 9 | ExDoc 10 | ExDoc 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 3/Codes/ExDoc/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | println!("The cube of 4 is {}", cube(4)); 3 | } 4 | 5 | /// Calculates the cube `val * val * val`. 6 | /// 7 | /// # Examples 8 | /// 9 | /// ``` 10 | /// let cube = cube(val); 11 | /// ``` 12 | pub fn cube(val: u32) -> u32 { 13 | // implementation goes here 14 | val * val * val 15 | } 16 | // The cube of 4 is 64 -------------------------------------------------------------------------------- /Chapter 3/Codes/Functions/Functions.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | 640cfbc1-a31d-4436-82db-d668804811c5 7 | exe 8 | Functions 9 | Functions 10 | Functions 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 3/Codes/Functions/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let hero1 = "Pac Man"; 3 | let hero2 = "Riddick"; 4 | greet(hero2); 5 | greet_both(hero1, hero2); 6 | 7 | let power = increment_power(1); 8 | println!("I am now at power level: {}", power); 9 | assert_eq!(2, power); 10 | } 11 | 12 | fn greet(name: &str) { 13 | println!("Hi mighty {}, what brings you here?", name); 14 | } 15 | 16 | fn greet_both(name1: &str, name2: &str) { 17 | greet(name1); 18 | greet(name2); 19 | } 20 | 21 | fn increment_power(power: i32) -> i32 { 22 | // if power < 100 { return 999; } 23 | println!("My power is going to increase:"); 24 | // power + 1; // results in: error: not all control paths return a value 25 | // return power + 1 // poor style 26 | power + 1 27 | } -------------------------------------------------------------------------------- /Chapter 3/Codes/IfElse/IfElse.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | 219ebc65-21e2-4ed0-bbd3-088b92ecaae2 7 | exe 8 | IfElse 9 | IfElse 10 | IfElse 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 3/Codes/IfElse/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let dead = false; 3 | let health = 48; 4 | 5 | if dead { 6 | println!("Game over!"); 7 | return; 8 | } 9 | 10 | if dead { 11 | println!("Game over!"); 12 | return; 13 | } else { 14 | println!("You still have a chance to win!"); 15 | } 16 | 17 | if health >= 50 { 18 | println!("Continue to fight!"); 19 | } else if health >= 20 { 20 | println!("Stop the battle and gain strength!"); 21 | } else { 22 | println!("Hide and try to recover!"); 23 | } 24 | 25 | let active = if health >= 50 { 26 | true 27 | } else { 28 | false 29 | }; 30 | println!("Am I active? {}", active); 31 | 32 | // alternative for ternary operator: 33 | let adult = true; 34 | let age = if adult { "+18" } else { "-18" }; 35 | println!("Age is {}", age); 36 | } 37 | // Stop the battle and gain strength! 38 | // Am I active? false 39 | // Age is +18 -------------------------------------------------------------------------------- /Chapter 3/Codes/IterStep/IterStep.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | 295a8ac2-bbc1-4997-9da1-5f52b608c09d 7 | exe 8 | IterStep 9 | IterStep 10 | IterStep 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 3/Codes/IterStep/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | // for i in std::iter::range_step(5i32, 0, -1) { // std::iter::range_step is deprecated 3 | for i in (1..6).rev() { 4 | print!("{} - ", i); 5 | } 6 | } 7 | // 5 - 4 - 3 - 2 - 1 - -------------------------------------------------------------------------------- /Chapter 3/Codes/Loops/Loops.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | 2516a609-7490-4734-9fc5-d3e847495b01 7 | exe 8 | Loops 9 | Loops 10 | Loops 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 3/Codes/Loops/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | // while loop: 3 | let max_power = 10; 4 | let mut power = 1; 5 | while power < max_power { 6 | print!("{} ", power); // prints without newline 7 | power += 1; // increment counter 8 | } 9 | 10 | // infinite loop with continue and break: 11 | println!("I gain Infinite power!"); 12 | loop { 13 | power += 1; 14 | if power == 42 { 15 | // Skip the rest of this iteration 16 | continue; 17 | } 18 | print!("{} ", power); 19 | if power == 50 { 20 | print!("OK, that's enough for today"); 21 | break; // exit the loop 22 | } 23 | } 24 | 25 | println!(""); 26 | // use of labels: 27 | 'outer: loop { 28 | print!("Entered the outer dungeon - "); 29 | 'inner: loop { 30 | println!("Entered the inner dungeon - "); 31 | // break; // breaks only from the inner loop 32 | break 'outer; // breaks to the outer loop 33 | } 34 | // error: unreachable statement 35 | // println!("This treasure can sadly never be reached - "); 36 | } 37 | println!("Exited the outer dungeon!"); 38 | 39 | // for in loop: 40 | for n in 1..11 { 41 | println!("The square of {} is {}", n, n * n); 42 | } 43 | 44 | let mut x = 10; 45 | for _ in 1 .. x { x -= 1; print!("."); } 46 | 47 | } 48 | // 1 2 3 4 5 6 7 8 9 I gain Infinite power! 49 | // 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 43 44 45 46 47 48 49 50 OK, that's enough for today 50 | // 51 | // Entered the outer dungeon 52 | // Entered the inner dungeon 53 | // Exited the outer dungeon! 54 | // 55 | // The square of 1 is 1 56 | // The square of 2 is 4 57 | // The square of 3 is 9 58 | // The square of 4 is 16 59 | // The square of 5 is 25 60 | // The square of 6 is 36 61 | // The square of 7 is 49 62 | // The square of 8 is 64 63 | // The square of 9 is 81 64 | // The square of 10 is 100 65 | // ......... -------------------------------------------------------------------------------- /Chapter 3/Codes/MyLib/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "MyLib" 3 | version = "0.1.0" 4 | authors = ["Chris Ohk "] 5 | 6 | [dependencies] 7 | -------------------------------------------------------------------------------- /Chapter 3/Codes/MyLib/MyLib.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | 999c869d-5688-4c83-8645-f39f8fa44af1 7 | exe 8 | MyLib 9 | MyLib 10 | MyLib 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 3/Codes/MyLib/src/main.rs: -------------------------------------------------------------------------------- 1 | #[test] 2 | fn it_works() { 3 | } 4 | -------------------------------------------------------------------------------- /Chapter 3/Codes/Random/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "Random" 3 | version = "0.1.0" 4 | authors = ["Chris Ohk "] 5 | 6 | [dependencies] 7 | rand = "0.3" -------------------------------------------------------------------------------- /Chapter 3/Codes/Random/Random.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | caf6b392-3194-4112-b371-dc5df5d74db5 7 | exe 8 | Random 9 | Random 10 | Random 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 3/Codes/Random/src/main.rs: -------------------------------------------------------------------------------- 1 | extern crate rand; 2 | 3 | fn main() { 4 | println!("Give me some random numbers:"); 5 | for _ in 0..5 { 6 | // let rnd = rand::random::(); // integers 32 bits 7 | // let rnd = rand::random::(); // positive integers 32 bits 8 | let rnd = (rand::random::() % 32) + 1; // numbers between 1 and 32 (not included) 9 | print!("{} / ", rnd); 10 | } 11 | } 12 | // Give me some random numbers: 13 | // 22 / 13 / 23 / 31 / 15 / 14 | // i32: 1874430781 / -282478132 / -1443939860 / 165374235 / 656033060 / 15 | // u32: 3186189551 / 1866438091 / 2909375433 / 664397067 / 3305048196 / -------------------------------------------------------------------------------- /Chapter 3/Exercises/Absolute/Absolute.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | 76228bf6-f99f-4a2d-8bf0-f71731d38342 7 | exe 8 | Absolute 9 | Absolute 10 | Absolute 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 3/Exercises/Absolute/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | assert_eq!(5, abs(-5)); 3 | } 4 | 5 | // fn abs(x: i32) -> u32 { 6 | // if x > 0 { x } 7 | // else { -x } 8 | // } 9 | // lines 6 and 7: 10 | // error: mismatched types: expected `u32`, found `i32` (expected u32, found i32) 11 | 12 | fn abs(x: i32) -> i32 { 13 | if x > 0 { 14 | x 15 | } else { 16 | -x 17 | } 18 | } -------------------------------------------------------------------------------- /Chapter 3/Exercises/IfReturn/IfReturn.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | e9f2f1ed-8747-4005-9702-15a27a9b65ce 7 | exe 8 | IfReturn 9 | IfReturn 10 | IfReturn 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 3/Exercises/IfReturn/src/main.rs: -------------------------------------------------------------------------------- 1 | fn verbose(x: i32) -> &'static str { 2 | let mut result: &'static str; 3 | if x < 10 { 4 | result = "less than 10"; 5 | } else { 6 | result = "10 or more"; 7 | } 8 | return result; 9 | } 10 | 11 | fn simple(x: i32) -> &'static str { 12 | if x < 10 { "less than 10" } 13 | else { "10 or more" } 14 | } 15 | 16 | fn main() { 17 | let n = 13; 18 | println!("verbose {}", verbose(n)); 19 | println!("simple {}", simple(n)); 20 | } 21 | // verbose 10 or more 22 | // simple 10 or more 23 | -------------------------------------------------------------------------------- /Chapter 3/Exercises/IfTest/IfTest.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | 181b7e9b-257d-46f2-9ff2-9b91989f2bbf 7 | exe 8 | IfTest 9 | IfTest 10 | IfTest 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 3/Exercises/IfTest/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | // 1) ; after expressions: 3 | let adult = true; 4 | let age = if adult { "+18"; } else { "-18"; }; 5 | println!("Age is {:?}", age); // Age is () 6 | // the following gives 7 | // error: mismatched types: expected `&str`, found `()` (expected &-ptr, found ()) 8 | // let age: &str = if adult { "+18"; } else { "-18"; }; 9 | 10 | // 2) block without { } ? 11 | let n = 10; 12 | // if n > 5 println!("n is bigger than 5"); 13 | // error: expected `{`, found `println` 14 | // help: place this code inside a block 15 | 16 | // 3) block without { } ? 17 | let health = -3; 18 | // let result = if health <=0 { "Game over man!" }; 19 | // error: if may be missing an else clause: expected `()`, 20 | // found `&'static str` (expected (), found &-ptr) 21 | // This doesn't work because the absence of the else part is viewed as else { () } 22 | //where () is a unit value of type (), which is not of type string 23 | // correction: 24 | let result = if health <=0 { "Game over man!" } else { "" }; 25 | } -------------------------------------------------------------------------------- /Chapter 4/Codes/Arrays/Arrays.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | cc9580f3-ffca-44c1-b597-f43593612323 7 | exe 8 | Arrays 9 | Arrays 10 | Arrays 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 4/Codes/Enums/Enums.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | b34803a1-9ab5-4c9b-9683-ee821215fa60 7 | exe 8 | Enums 9 | Enums 10 | Enums 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 4/Codes/Enums/src/main.rs: -------------------------------------------------------------------------------- 1 | use PlanetaryMonster::MarsMonster; 2 | 3 | enum Compass { 4 | North, South, East, West 5 | } 6 | 7 | type species = &'static str; 8 | 9 | enum PlanetaryMonster { 10 | VenusMonster(species, i32), 11 | MarsMonster(species, i32) 12 | } 13 | 14 | fn main() { 15 | let direction = Compass::West; 16 | let martian = PlanetaryMonster::MarsMonster("Chela", 42); 17 | let martian = MarsMonster("Chela", 42); 18 | 19 | // using enum values: 20 | // error: binary operation `==` cannot be applied to type `Compass` 21 | // if direction == Compass::East { 22 | // println!("Go to the east"); 23 | // } 24 | 25 | match direction { 26 | Compass::North => println!("Go to the North!"), 27 | Compass::East => println!("Go to the East!"), 28 | Compass::South => println!("Go to the South!"), 29 | Compass::West => println!("Go to the West!"), 30 | } 31 | } 32 | // Go to the West! -------------------------------------------------------------------------------- /Chapter 4/Codes/Input/Input.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | dc0176e1-de34-4512-9c83-d6161fc2145a 7 | exe 8 | Input 9 | Input 10 | Input 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 4/Codes/Input/src/main.rs: -------------------------------------------------------------------------------- 1 | use std::io; 2 | 3 | fn main() { 4 | println!("What's your name, noble warrior?"); 5 | let mut buf = String::new(); 6 | io::stdin().read_line(&mut buf) 7 | .ok() 8 | .expect("Failed to read line"); 9 | let name = buf.trim(); 10 | println!("{}, that's a mighty name indeed!", name); 11 | } 12 | // What's your name, noble warrior? 13 | // Riddick 14 | // Riddick, that's a mighty name indeed! -------------------------------------------------------------------------------- /Chapter 4/Codes/PatternMatch/PatternMatch.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | 10663ef8-1212-4cbc-b3cc-f1e2d5fd88d6 7 | exe 8 | PatternMatch 9 | PatternMatch 10 | PatternMatch 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 4/Codes/PatternMatch/src/main.rs: -------------------------------------------------------------------------------- 1 | use std::io; 2 | 3 | fn main() { 4 | print!("Give a positive secret number: "); 5 | let mut buf = String::new(); 6 | io::stdin().read_line(&mut buf) 7 | .ok() 8 | .expect("Failed to read number"); 9 | let input_num: Result = buf.trim().parse(); 10 | 11 | // println!("Unwrap found {}", input_num.unwrap()); 12 | 13 | match input_num { 14 | Ok(num) => println!("{}", num), 15 | Err(ex) => println!("Please input an integer number! {}", ex) 16 | }; 17 | 18 | // binding the value of a match: 19 | // let num = match input_num { 20 | // Ok(num) => num, 21 | // Err(_) => 0 22 | // }; 23 | 24 | let input_num: Result = buf.trim().parse(); 25 | // alternative way for destructuring the Result: 26 | if let Ok(val) = input_num { 27 | println!("Matched {:?}!", val); 28 | } else { 29 | println!("No match!"); 30 | } 31 | 32 | while let Ok(val) = input_num { 33 | println!("Matched {:?}!", val); 34 | if val == 42 { break } 35 | } 36 | } 37 | // Give a positive secret number: 42 38 | // 42 39 | // Matched 42! 40 | // Matched 42! 41 | -------------------------------------------------------------------------------- /Chapter 4/Codes/PatternMatch2/PatternMatch2.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | 591f5a2c-6e0d-4d77-9235-37e4a3e752a5 7 | exe 8 | PatternMatch2 9 | PatternMatch2 10 | PatternMatch2 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 4/Codes/PatternMatch2/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | // exhaustive match with _: 3 | let magician = "Gandalf"; 4 | match magician { 5 | "Gandalf" => println!("A good magician!"), 6 | "Sauron" => println!("A magician turned bad!"), 7 | _ => println!("No magician turned up!") 8 | } 9 | 10 | // matching several values in a branch: 11 | let magical_number: i32 = 42; 12 | match magical_number { 13 | // Match a single value 14 | 1 => println!("Unity!"), 15 | // Match several values 16 | 2 | 3 | 5 | 7 | 11 => println!("Ok, these are primes"), 17 | // Match an inclusive range 18 | // 40...42 => println!("It is contained in this range"), 19 | num @ 40...42 => println!("{} is contained in this range ", num), 20 | // Handle the rest of cases 21 | _ => println!("No magic at all!"), 22 | } 23 | 24 | // destructuring values and using guards: 25 | let loki = ("Loki", true, 800u32); 26 | match loki { 27 | (name, demi, _) if demi => { 28 | print!("This is a demigod "); 29 | println!("called {}", name); 30 | } 31 | (name, _, _) if name == "Thor" => println!("This is Thor!"), 32 | (_, _, pow) if pow <= 1000 => println!("This is a powerless god"), 33 | _ => println!("This is something else") 34 | } 35 | } 36 | // A good magician! 37 | // 42 is contained in this range 38 | // This is a demigod called Loki -------------------------------------------------------------------------------- /Chapter 4/Codes/Strings/Strings.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | 6231b550-6b67-4788-95c5-5102a0d1b81c 7 | exe 8 | Strings 9 | Strings 10 | Strings 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 4/Codes/Structs/Structs.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | 1b8aa433-f048-4e30-ba1c-588bcb5fc497 7 | exe 8 | Structs 9 | Structs 10 | Structs 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 4/Codes/Structs/src/main.rs: -------------------------------------------------------------------------------- 1 | struct Player { 2 | nname: &'static str, // nickname 3 | health: i32, 4 | level: u8 5 | } 6 | 7 | fn main() { 8 | struct Scoreu; // unit struct 9 | 10 | // tuple structs: 11 | struct Score(i32, u8); 12 | let score1 = Score(73, 2); // make (instantiate) a tuple struct 13 | let Score(h, l) = score1; // // extract values by destructuring 14 | println!("Health {} - Level {}", h, l); 15 | 16 | // newtype: 17 | struct Kilograms(u32); 18 | let weight = Kilograms(250); 19 | let Kilograms(kgm) = weight; // extracting kgm 20 | println!("weight is {} kilograms", kgm); 21 | 22 | // struct: 23 | let mut pl1 = Player{ nname: "Dzenan", health: 73, level: 2 }; 24 | println!("Player {} is at level {}", pl1.nname, pl1.level); 25 | pl1.level = 3; 26 | 27 | // pointers do automatic dereferencing when accessing data structure elements: 28 | let ps = &Player{ nname: "John", health: 95, level: 1 }; 29 | println!("{} == {}", ps.nname, (*ps).nname); 30 | 31 | // destructuring a struct: 32 | let Player{ health: ht, nname: nn, .. } = pl1; 33 | println!("Player {} has health {}", nn, ht); 34 | } 35 | // Health 73 - Level 2 36 | // weight is 250 kilograms 37 | // Player Dzenan is at level 2 38 | // John == John 39 | // Player Dzenan has health 73 -------------------------------------------------------------------------------- /Chapter 4/Codes/Tuples/Tuples.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | c98e0d8d-edaf-4b30-8797-e3f54158564e 7 | exe 8 | Tuples 9 | Tuples 10 | Tuples 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 4/Codes/Tuples/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let thor = ("Thor", true, 3500u32); 3 | println!("{:?}", thor); // ("Thor", true, 3500) 4 | // type of thor: (&str, bool, u32) 5 | println!("{} - {} - {}", thor.0, thor.1, thor.2); 6 | 7 | // destructuring: 8 | let (name, _, power) = thor; 9 | println!("{} has {} points of power", name, power); 10 | 11 | // one-element tuple: 12 | let one = (1,); 13 | 14 | // function returning a tuple and destructuring the return value: 15 | let (god, strength) = increase_power(thor.0, thor.2); 16 | println!("This god {} has now {} strength", god, strength); 17 | } 18 | 19 | fn increase_power(name: &str, power: u32) -> (&str, u32) { 20 | if power > 1000 { 21 | return (name, power * 3); 22 | } else { 23 | return (name, power * 2); 24 | } 25 | } 26 | 27 | // ("Thor", true, 3500u) 28 | // Thor - true - 3500 29 | // Thor has 3500 points of power 30 | // This god Thor has now 10500 strength -------------------------------------------------------------------------------- /Chapter 4/Exercises/CharsString/CharsString.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | 6616b3e4-e302-40d0-b8f1-07c4db4d23f5 7 | exe 8 | CharsString 9 | CharsString 10 | CharsString 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 4/Exercises/CharsString/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let magician = "Merlin"; 3 | // does not compile: 4 | // error: the trait `core::ops::Index<_>` is not implemented 5 | // for the type `collections::string::String` [E0277] 6 | // in Unicode: each character can be a variable number of bytes 7 | // println!("{}", (magician.to_string())[0]); 8 | let mut str = String::new(); 9 | str.push_str("Gandalf"); 10 | // does not compile: 11 | // error: the trait `core::ops::Index<_>` is not implemented 12 | // for the type `collections::string::String` [E0277] 13 | // in Unicode: each character can be a variable number of bytes 14 | // println!("{}", str[3]); 15 | 16 | // solution: use an iterator: 17 | let greeting = "Hello, ??!"; 18 | println!("Bytes:"); 19 | for c in greeting.bytes() { 20 | print!("{} - ", c); 21 | } 22 | println!(""); 23 | println!("Chars:"); 24 | for c in greeting.chars() { 25 | print!("{} - ", c); 26 | } 27 | } 28 | // Bytes: 29 | // 72 - 101 - 108 - 108 - 111 - 44 - 32 - 228 - 184 - 150 - 231 - 149 - 140 - 33 - 30 | // Chars: 31 | // H - e - l - l - o - , - - ? - ? - ! - -------------------------------------------------------------------------------- /Chapter 4/Exercises/Monster/Monster.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | f7cd3070-b61a-4e34-a7b9-19dd8b90cb56 7 | exe 8 | Monster 9 | Monster 10 | Monster 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 4/Exercises/Monster/src/main.rs: -------------------------------------------------------------------------------- 1 | struct Monster { 2 | health: i32, 3 | damage: i32 4 | } 5 | 6 | fn main() { 7 | let m = Monster { health: 10, damage: 20 }; 8 | 9 | println!("{}", m.health); 10 | println!("{}", m.damage); 11 | } 12 | // 10 13 | // 20 -------------------------------------------------------------------------------- /Chapter 4/Exercises/PatternMatch/PatternMatch.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | f0fe0ce3-ded8-40be-9191-4fe889e65ba4 7 | exe 8 | PatternMatch 9 | PatternMatch 10 | PatternMatch 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 4/Exercises/PatternMatch/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | // exhaustive match with _: 3 | let magician = "Gandalf"; 4 | match magician { 5 | "Gandalf" => println!("A good magician!"), 6 | _ => println!("No magician turned up!"), 7 | // "Sauron" => println!("A magician turned bad!") // error: unreachable pattern [E0001] 8 | } 9 | } -------------------------------------------------------------------------------- /Chapter 4/Exercises/TuplesEx/TuplesEx.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | 58635dd8-e273-4ed7-8054-a08b061b5f88 7 | exe 8 | TuplesEx 9 | TuplesEx 10 | TuplesEx 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 4/Exercises/TuplesEx/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | // (2, 'a') == (5, false); 3 | // error: mismatched types: expected `char`, found `bool` (expected char, found bool) 4 | 5 | // mutability of tuples: 6 | let thor = (4, 5.0, false, "hello"); 7 | println!("{} - {} - {}", thor.0, thor.1, thor.2); 8 | // thor.0 = 42; // error: cannot assign to immutable anonymous field `thor.0` 9 | 10 | let mut thor = (4, 5.0, false, "hello"); 11 | println!("{} - {} - {}", thor.0, thor.1, thor.2); 12 | thor.0 = 42; // ok! 13 | println!("{} - {} - {}", thor.0, thor.1, thor.2); 14 | 15 | let empty_tup = (); 16 | if () == () { 17 | println!("The unit value is an empty tuple"); 18 | } 19 | } 20 | // 4 - 5 - false 21 | // 4 - 5 - false 22 | // 42 - 5 - false 23 | // The unit value is an empty tuple -------------------------------------------------------------------------------- /Chapter 5/Codes/AdaptersConsumers/AdaptersConsumers.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | 42e5b451-4000-4bfc-b791-ad48393acf19 7 | exe 8 | AdaptersConsumers 9 | AdaptersConsumers 10 | AdaptersConsumers 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 5/Codes/AdaptersConsumers/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | // CONSUMERS: 3 | println!("CONSUMERS: "); 4 | // collect: 5 | let rng = 0..1000; 6 | let rngvec = rng.collect::>(); 7 | // alternative: 8 | // let rngvec: Vec = rng.collect(); 9 | println!("{:?}", rngvec); 10 | 11 | // find: 12 | let mut rng = 0..1000; 13 | let forty_two = rng.find(|n| *n >= 42); 14 | println!("{:?}", forty_two); // Some(42) 15 | // find needs a mutable variable, and moves it 16 | 17 | // ADAPTERS: 18 | // filter: 19 | println!("ADAPTERS: "); 20 | println!("FILTER:"); 21 | rng = 0..1000; 22 | let rng_even = rng.filter(|n| is_even(*n)) 23 | .collect::>(); 24 | println!("{:?}", rng_even); 25 | 26 | // alternative without collect: 27 | let rng = 1..100; 28 | let rng_even = rng.filter(|n| is_even(*n)); 29 | for x in rng_even { 30 | println!("{}", x); 31 | } 32 | 33 | // map: 34 | println!("MAP:"); 35 | let rng = 0..1000; 36 | let rng_even_pow3 = rng.filter(|n| is_even(*n)) 37 | .map(|n| n * n * n) 38 | .collect::>(); 39 | println!("{:?}", rng_even_pow3); 40 | println!("TAKE:"); 41 | let rng = 0..1000; 42 | let rng_even_pow3_first5 = rng.filter(|n| is_even(*n)) 43 | .map(|n| n * n * n) 44 | .take(5) 45 | .collect::>(); 46 | println!("{:?}", rng_even_pow3_first5); 47 | } 48 | 49 | fn is_even(n: i32) -> bool { 50 | n % 2 == 0 51 | } 52 | // CONSUMERS: 53 | // [0, 1, 2, 3, 4, ..., 999 ] 54 | // Some(42) 55 | // ADAPTERS: 56 | // FILTER: 57 | // [0, 2, 4, ..., 996, 998] 58 | // MAP: 59 | // [0, 8, 64, ..., 988047936, 994011992] 60 | // TAKE: 61 | // [0, 8, 64, 216, 512] -------------------------------------------------------------------------------- /Chapter 5/Codes/Errors/Errors.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | d9124f77-c1b5-4949-be4d-49bf258ea4f6 7 | exe 8 | Errors 9 | Errors 10 | Errors 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 5/Codes/Errors/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | // panics: 3 | let x = 3; 4 | let y = 0; 5 | // x / y; // thread '
' panicked at 'attempted to divide by zero' 6 | if y == 0 { panic!("Division by 0 occurred, exiting"); } 7 | println!("{}", div(x, y)); // returns 0 if y = 5 8 | 9 | // assert!(x == 5); // thread '
' panicked at 'assertion failed: x == 5' 10 | // assert_eq!(x, 5); // thread '
' panicked at 'assertion failed: (left: `3`, right: `5`)', 11 | // unreachable!(); // thread '
' panicked at 'internal error: entered unreachable code' 12 | } 13 | 14 | fn div(x: i32, y: i32) -> f32 { 15 | (x / y) as f32 16 | } -------------------------------------------------------------------------------- /Chapter 5/Codes/Generics/Generics.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | b8be256e-d46f-4ad6-ab2b-956312d54163 7 | exe 8 | Generics 9 | Generics 10 | Generics 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 5/Codes/Generics/src/main.rs: -------------------------------------------------------------------------------- 1 | use std::f32; 2 | 3 | struct Person { 4 | name: &'static str, 5 | id: i32 6 | } 7 | 8 | struct Pair { 9 | first: T, 10 | second: T, 11 | } 12 | 13 | fn main() { 14 | // generic structs: 15 | let magic_pair: Pair = Pair { first: 7, second: 42 }; 16 | let pair_of_magicians: Pair<&str> = Pair { first: "Gandalf", second: "Sauron" }; 17 | let a = second(magic_pair); 18 | 19 | // using Option 20 | let x: Option = Some(5); 21 | let pi: Option = Some(3.14159265359); 22 | let none: Option = None; 23 | let none2 = None::; 24 | let name: Option<&str> = Some("Joyce"); 25 | // let magic: Option = Some(42); // error: mismatched types 26 | 27 | let p1 = Person{ name: "James Bond", id: 7 }; 28 | let p2 = Person{ name: "Vin Diesel", id: 12 }; 29 | let p3 = Person{ name: "Robin Hood", id: 42 }; 30 | let op1: Option = Some(p1); 31 | let pvec: Vec = vec![p2, p3]; // type annotation is not necessary 32 | // let pvec = vec![p2, p3]; 33 | 34 | // using Result 35 | let m = sqroot(42.0); 36 | // let m = sqroot(-5.0); 37 | match m { 38 | Ok(sq) => println!("The square root of 42 is {}", sq), 39 | Err(str) => println!("{}", str) 40 | } 41 | } 42 | 43 | fn sqroot(r: f32) -> Result { 44 | if r < 0.0 { 45 | return Err("Number cannot be negative!".to_string()); 46 | } 47 | Ok(f32::sqrt(r)) 48 | } 49 | 50 | fn second(pair: Pair) { 51 | pair.second; 52 | } 53 | // The square root of 42 is 6.480741 54 | // for m == -5.0: Number cannot be negative! -------------------------------------------------------------------------------- /Chapter 5/Codes/HigherFunctions/HigherFunctions.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | 996eb787-e9d1-477d-8855-8e017fec98d9 7 | exe 8 | HigherFunctions 9 | HigherFunctions 10 | HigherFunctions 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 5/Codes/Iterators/Iterators.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | bdfdbb46-0bbe-48af-95d2-2f1752f643b6 7 | exe 8 | Iterators 9 | Iterators 10 | Iterators 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 5/Codes/Iterators/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | // iterating over a range: 3 | let mut rng = 0..7; 4 | 5 | println!("> {:?}", rng.next()); // Some(0) 6 | println!("> {:?}", rng.next()); // Some(1) 7 | 8 | loop { 9 | match rng.next() { 10 | Some(x) => { 11 | print!("{}", x); 12 | }, 13 | None => { break } 14 | } 15 | } 16 | println!(""); 17 | 18 | // shorter way: 19 | let mut rng = 0..7; 20 | for n in rng { 21 | print!("{} - ", n); 22 | } // 0 - 1 - 2 - 3 - 4 - 5 - 6 - 23 | println!(""); 24 | 25 | // iterating over arrays and vectors: 26 | let aliens = ["Cherfer", "Fynock", "Shirack", "Zuxu"]; 27 | println!("Here are the aliens: "); 28 | for alien in aliens.iter() { 29 | print!("{} / ", alien) 30 | } 31 | // shorter way: 32 | println!("Here are the aliens again: "); 33 | for alien in &aliens { 34 | print!("{} / ", alien) 35 | } 36 | println!(""); 37 | 38 | println!("Here are the aliens in reverse: "); 39 | for alien in aliens.iter().rev() { 40 | print!("{} / ", alien) 41 | } 42 | 43 | // lazy iterator: 44 | let rng = 0..1000_000; 45 | } 46 | // > Some(0) 47 | // > Some(1) 48 | // 23456 49 | // 0 - 1 - 2 - 3 - 4 - 5 - 6 - 50 | // Here are the aliens: 51 | // Cherfer / Fynock / Shirack / Zuxu / 52 | // Here are the aliens again: 53 | // Cherfer / Fynock / Shirack / Zuxu / 54 | // Here are the aliens in reverse: 55 | // Zuxu / Shirack / Fynock / Cherfer / -------------------------------------------------------------------------------- /Chapter 5/Codes/Methods/Methods.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | 642e20c9-4047-46c3-b820-d048d7f8dc61 7 | exe 8 | Methods 9 | Methods 10 | Methods 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 5/Codes/Methods/src/main.rs: -------------------------------------------------------------------------------- 1 | struct Alien { 2 | health: u32, 3 | damage: u32 4 | } 5 | 6 | impl Alien { 7 | fn new(mut h: u32, d: u32) -> Alien { 8 | // constraints: 9 | if h > 100 { h = 100; } 10 | Alien {health: h, damage: d} 11 | } 12 | 13 | fn warn() -> &'static str { 14 | "Leave this planet immediately or perish!" 15 | } 16 | 17 | fn attack(&self) { 18 | println!("I attack! Your health lowers with {} damage points.", self.damage); 19 | } 20 | 21 | // multiple errors: 22 | // cannot assign to immutable field self.health 23 | // solution: &mut self 24 | // duplicate definition of value `attack` 25 | // solution: give method a different name 26 | // fn attack(&mut self) { 27 | // self.health -= 10; 28 | // } 29 | 30 | fn attack_and_suffer(&mut self, damage_from_other: u32) { 31 | self.health -= damage_from_other; 32 | } 33 | } 34 | 35 | fn main() { 36 | let mut bork = Alien{ health: 100, damage: 5 }; 37 | let mut berserk = Alien::new(150, 15); 38 | println!("The berserk's health at birth is: {}", berserk.health); 39 | println!("{}", Alien::warn()); 40 | berserk.attack(); 41 | println!("The berserk's health is: {}", berserk.health); 42 | berserk.attack_and_suffer(31); 43 | println!("After attack the berserk's health is: {}", berserk.health); 44 | } 45 | // The berserk's health at birth is: 100 46 | // Leave this planet immediately or perish! 47 | // I attack! Your health lowers with 15 damage points. 48 | // The berserk's health is: 100 49 | // After attack the berserk's health is: 69 -------------------------------------------------------------------------------- /Chapter 5/Codes/TraitConstraints/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "TraitConstraints" 3 | version = "0.1.0" 4 | authors = ["Chris Ohk "] 5 | 6 | [dependencies] 7 | num = "*" -------------------------------------------------------------------------------- /Chapter 5/Codes/TraitConstraints/TraitConstraints.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | 4313c201-ccca-4524-a53b-1e698b2f0938 7 | exe 8 | TraitConstraints 9 | TraitConstraints 10 | TraitConstraints 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 5/Codes/TraitConstraints/src/main.rs: -------------------------------------------------------------------------------- 1 | extern crate num; 2 | use num::traits::Float; 3 | 4 | fn main() { 5 | println!("The square root of {} is {:?}", 42.0f32, sqroot(42.0f32) ); 6 | println!("The square root of {} is {:?}", 42.0f64, sqroot(42.0f64) ); 7 | } 8 | 9 | fn sqroot(r: T) -> Result { 10 | if r < num::zero() { 11 | return Err("Number cannot be negative!".to_string()); 12 | } 13 | Ok(num::traits::Float::sqrt(r)) 14 | } 15 | 16 | // trait constraint written with where clause syntax: 17 | fn sqroot2(r: T) -> Result where T: num::traits::Float { 18 | if r < num::zero() { 19 | return Err("Number cannot be negative!".to_string()); 20 | } 21 | Ok(num::traits::Float::sqrt(r)) 22 | } 23 | // The square root of 42 is Ok(6.480741) 24 | // The square root of 42 is Ok(6.480741) 25 | 26 | // fn multc(x: T, y: U) {} 27 | // fn multc(x: T, y: U) where T: Trait1, U: Trait1 + Trait2 {} 28 | 29 | -------------------------------------------------------------------------------- /Chapter 5/Codes/Traits/Traits.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | 15c87ac3-e977-432f-8797-90384d7de759 7 | exe 8 | Traits 9 | Traits 10 | Traits 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 5/Codes/Traits/src/main.rs: -------------------------------------------------------------------------------- 1 | struct Alien { health: u32, damage: u32 } 2 | 3 | #[derive(Debug)] 4 | struct Zombie { health: u32, damage: u32 } 5 | 6 | struct Predator { health: u32, damage: u32 } 7 | 8 | trait Monster { 9 | fn new(hlt: u32, dam: u32) -> Self; 10 | 11 | fn attack(&self); 12 | fn noise(&self) -> &'static str; 13 | 14 | fn attacks_with_sound(&self) { 15 | println!("The Monster attacks by making an awkward sound {}", self.noise()); 16 | } 17 | } 18 | 19 | impl Monster for Alien { 20 | fn new(mut h: u32, d: u32) -> Alien { 21 | // constraints: 22 | if h > 100 { h = 100; } 23 | Alien { health: h, damage: d } 24 | } 25 | 26 | fn attack(&self) { 27 | println!("I attack! Your health lowers with {} damage points.", self.damage); 28 | } 29 | 30 | fn noise(&self) -> &'static str { 31 | "Shriek!" 32 | } 33 | } 34 | 35 | impl Monster for Zombie { 36 | fn new(mut h: u32, d: u32) -> Zombie { 37 | // constraints: 38 | if h > 100 { h = 100; } 39 | Zombie { health: h, damage: d } 40 | } 41 | 42 | fn attack(&self) { 43 | println!("The Zombie bites! Your health lowers with {} damage points.", 2 * self.damage); 44 | } 45 | 46 | fn noise(&self) -> &'static str { 47 | "Aaargh!" 48 | } 49 | } 50 | 51 | // Predator still has to implement new and noise methods: 52 | // impl Monster for Predator { 53 | // fn attack(&self) { 54 | // println!("I bite you! Your health lowers with {} damage points.", 3 * self.damage); 55 | // } 56 | // } 57 | 58 | fn main() { 59 | let zmb1 = Zombie { health: 75, damage: 15 }; 60 | println!("Oh no, I hear: {}", zmb1.noise()); 61 | zmb1.attack(); 62 | println!("{:?}", zmb1); 63 | } 64 | // Oh no, I hear: Aaargh! 65 | // The Zombie bites! Your health lowers with 30 damage points. 66 | // Zombie { health: 75, damage: 15 } -------------------------------------------------------------------------------- /Chapter 5/Exercises/Complex/Complex.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | e7814865-8a5f-4b99-88e6-3ead889fe5e5 7 | exe 8 | Complex 9 | Complex 10 | Complex 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 5/Exercises/Complex/src/main.rs: -------------------------------------------------------------------------------- 1 | use std::f64; 2 | 3 | struct Complex { 4 | real: f64, 5 | imag: f64 6 | } 7 | 8 | impl Complex { 9 | fn new(re: f64, im: f64) -> Complex { 10 | Complex{ real: re, imag: im } 11 | } 12 | 13 | fn to_string(&self) -> String { 14 | if self.imag > 0.0 { format!("{} + {}i", self.real, self.imag) } 15 | else if self.imag < 0.0 { format!("{} - {}i", self.real, f64::abs(self.imag)) } 16 | else { format!("{}", self.real) } 17 | } 18 | 19 | fn add(&self, c: Complex) -> Complex { 20 | Complex{ real: self.real + c.real, imag: self.imag + c.imag } 21 | } 22 | 23 | fn times_ten(&mut self) { 24 | self.real = 10.0 * self.real; 25 | self.imag = 10.0 * self.imag; 26 | } 27 | 28 | fn abs(&self) -> f64 { 29 | f64::sqrt((self.real * self.real) + (self.imag * self.imag)) 30 | } 31 | 32 | } 33 | 34 | fn main() { 35 | let c1 = Complex{ real: 2.0, imag: 5.0 }; 36 | // same number, but with constructor new: 37 | let mut c2 = Complex::new(2.0, 5.0); 38 | // println!("{:?}", c1); 39 | println!("{}", c2.to_string()); // 2 + 5i 40 | let c3 = Complex::new(2.0, -5.0); 41 | println!("{}", c3.to_string()); // 2 - 5i 42 | let c4 = Complex::new(1.2, 4.2); 43 | println!("{}", c2.add(c4).to_string()); // 3.2 + 9.2i 44 | println!("{}", c2.add(c3).to_string()); // 4 45 | // println!("{}", c2.times_ten().to_string()); // 20 + 50i 46 | c2.times_ten(); 47 | println!("{}", c2.to_string()); // 20 + 50i 48 | println!("{}", c1.abs()); // 5.385165 49 | } -------------------------------------------------------------------------------- /Chapter 5/Exercises/DrawTrait/DrawTrait.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | f13bca09-05ba-40ed-86ae-7985e028d62a 7 | exe 8 | DrawTrait 9 | DrawTrait 10 | DrawTrait 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 5/Exercises/DrawTrait/src/main.rs: -------------------------------------------------------------------------------- 1 | trait Draw { 2 | fn draw(&self); 3 | } 4 | 5 | struct S1 { 6 | data_s1: i32 7 | } 8 | 9 | struct S2 { 10 | data_s2: f64 11 | } 12 | 13 | impl Draw for S1 { 14 | fn draw(&self) { 15 | println!("{}", self.data_s1); 16 | } 17 | } 18 | 19 | impl Draw for S2 { 20 | fn draw(&self) { 21 | println!("{}", self.data_s2); 22 | } 23 | } 24 | 25 | fn draw_object(object: T) { 26 | println!("Going to draw an object:"); 27 | object.draw(); 28 | println!("Look how beautiful!"); 29 | } 30 | 31 | 32 | fn main() { 33 | let s1 = S1 { data_s1: 42 }; 34 | let s2 = S2 { data_s2: 42.0 }; 35 | draw_object(s1); // OK, S1 implements Draw. 36 | draw_object(s2); // OK, S2 implements Draw. 37 | // draw_object(42.0); // error: the trait `Draw` is not implemented for the type `_` 38 | } 39 | // Going to draw an object: 40 | // 42 41 | // Look how beautiful! 42 | // Going to draw an object: 43 | // 42 44 | // Look how beautiful! -------------------------------------------------------------------------------- /Chapter 5/Exercises/Fold/Fold.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | 115db562-609b-486a-8bc1-5f5dcc6550de 7 | exe 8 | Fold 9 | Fold 10 | Fold 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 5/Exercises/Fold/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let sum = (0..101).fold(0, |sum, n| sum + n); 3 | println!("{}", sum); // 5050 4 | 5 | let prcub = (1..6).fold(1, |prcub, n| prcub * (n * n * n)); 6 | println!("{}", prcub); // 1728000 7 | 8 | let arr = [1, 9, 2, 3, 14, 12]; 9 | let res = arr.iter().fold(0, |acc, item| acc - *item); 10 | println!("{}", res) // -41 11 | } -------------------------------------------------------------------------------- /Chapter 5/Exercises/RangeNext/RangeNext.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | a0b3b1b4-d557-4ad9-a79c-35fcdc77fd02 7 | exe 8 | RangeNext 9 | RangeNext 10 | RangeNext 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 5/Exercises/RangeNext/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let mut rng = 0..7; 3 | 4 | loop { 5 | match rng.next() { 6 | Some(val) => print!("{} - ", val), 7 | None => break 8 | } 9 | } 10 | } 11 | // 0 - 1 - 2 - 3 - 4 - 5 - 6 - -------------------------------------------------------------------------------- /Chapter 6/Codes/Boxes1/Boxes1.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | fa804ce7-1275-44de-802e-55ee0a5b10e1 7 | exe 8 | Boxes1 9 | Boxes1 10 | Boxes1 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 6/Codes/Boxes1/src/main.rs: -------------------------------------------------------------------------------- 1 | struct Alien { 2 | planet: String, 3 | n_tentacles: u32, 4 | } 5 | 6 | fn main() { 7 | let mut a1 = Box::new(Alien{ planet: "Mars".to_string(), n_tentacles: 4 }); 8 | println!("{}", a1.n_tentacles); // 4 9 | 10 | let a2 = &mut a1; 11 | println!("{}", a2.planet ); // Mars 12 | a2.n_tentacles = 5; 13 | // error: cannot borrow `a1.n_tentacles` as immutable because `a1` is also borrowed as mutable 14 | // println!("{}", a1.n_tentacles); 15 | // error: cannot assign to `a1.planet` because it is borrowed 16 | // a1.planet = "Pluto".to_string(); 17 | 18 | // putting simple values on the heap: 19 | let n = Box::new(42); 20 | println!("{}", n); // 42 21 | // *n = 67; // error: cannot assign to immutable `Box` content `*n` 22 | let p = *n; 23 | println!("{}", p); // 42 24 | 25 | // p = 67; // error: re-assignment of immutable variable `p` 26 | // this is allowed: 27 | let mut p = *n; 28 | p = 67; 29 | println!("{}", p); // 67 30 | println!("n now still has value {}", n); // 42 31 | 32 | // another reference to n: 33 | let q = &*n; 34 | // let q = &42; 35 | println!("{}", q); // 42 36 | println!("{}", square(q)); // 1764 37 | } 38 | 39 | fn square(k: &i32) -> i32 { 40 | *k * *k 41 | } -------------------------------------------------------------------------------- /Chapter 6/Codes/Boxes2/Boxes2.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | f228ddc5-ee6a-4bfa-b1dd-9155f84d5d43 7 | exe 8 | Boxes2 9 | Boxes2 10 | Boxes2 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 6/Codes/Boxes2/src/main.rs: -------------------------------------------------------------------------------- 1 | struct Alien { 2 | planet: String, 3 | n_tentacles: u32, 4 | } 5 | 6 | fn main() { 7 | // mutability can be changed by transfering ownership: 8 | let n = Box::new(42); 9 | let mut m = n; 10 | *m = 67; 11 | // println!("{}", n); // error: use of moved value: `n` 12 | println!("{}", m); // 67 13 | 14 | let mut a1 = Box::new(Alien{ planet: "Mars".to_string(), n_tentacles: 4 }); 15 | // a move occurs here because it is a Box type: 16 | let a2 = a1; 17 | //println!("{}", a1.n_tentacles); // error: use of moved value: `a1.n_tentacles` 18 | // a2.n_tentacles = 5; // cannot assign to immutable field a2.n_tentacles 19 | println!("{}", a2.n_tentacles); // 4 20 | use_alien(a2); 21 | // use_alien2(&*a2); 22 | // println!("{}", a2.n_tentacles); // error: use of moved value: `a2.n_tentacles` 23 | } 24 | 25 | fn use_alien(a: Box) { 26 | println!("An alien from planet {} is freed", a.planet); 27 | } 28 | 29 | fn use_alien2(a: &Alien) { 30 | println!("An alien from planet {} is freed", a.planet); 31 | } 32 | 33 | struct Recurs { 34 | list: Vec, 35 | rec_list: Option> 36 | } 37 | 38 | // 67 39 | // 4 40 | // An alien from planet Mars is freed -------------------------------------------------------------------------------- /Chapter 6/Codes/Errors/Errors.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | de6ed777-9808-4331-9e25-7265d87721e3 7 | exe 8 | Errors 9 | Errors 10 | Errors 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 6/Codes/Errors/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | // panics: 3 | let x = 3; 4 | let y = 0; 5 | // x / y; // thread '
' panicked at 'attempted to divide by zero' 6 | if y == 0 { panic!("Division by 0 occurred, exiting"); } 7 | println!("{}", div(x, y)); // returns 0 if y = 5 8 | 9 | // assert!(x == 5); // thread '
' panicked at 'assertion failed: x == 5' 10 | // assert_eq!(x, 5); // thread '
' panicked at 'assertion failed: (left: `3`, right: `5`)', 11 | // unreachable!(); // thread '
' panicked at 'internal error: entered unreachable code' 12 | } 13 | 14 | fn div(x: i32, y: i32) -> f32 { 15 | (x / y) as f32 16 | } -------------------------------------------------------------------------------- /Chapter 6/Codes/Lifetimes/Lifetimes.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | 21d5346f-c54e-48be-bcad-c93de604b5fb 7 | exe 8 | Lifetimes 9 | Lifetimes 10 | Lifetimes 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 6/Codes/Lifetimes/src/main.rs: -------------------------------------------------------------------------------- 1 | struct Magician { 2 | name: &'static str, 3 | power: u32 4 | } 5 | 6 | // this code does not compile: 7 | // error: missing lifetime specifier [E0106] 8 | // struct MagicNumbers { 9 | // magn1: &u32, 10 | // magn2: &u32 11 | // } 12 | 13 | // this code is ok, both the struct and the fields have lifetime 'a: 14 | struct MagicNumbers<'a> { 15 | magn1: &'a u32, 16 | magn2: &'a u32 17 | } 18 | 19 | #[derive(Debug, Copy, Clone)] 20 | struct MagicNumber { 21 | value: u64 22 | } 23 | // impl Copy for MagicNumber {} 24 | 25 | fn main() { 26 | // lifetimes restricted to a function: 27 | let n = 42u32; 28 | // copy behaviour: 29 | // no move, only a copy of the value from n to n2: 30 | let n2 = n; 31 | println!("The value of n2 is {}, the same as n", n2); 32 | 33 | life(n); 34 | // println!("{}", m); // error: unresolved name `m`. 35 | // println!("{}", o); // error: unresolved name `o`. 36 | 37 | // lifetime restricted to a code block: 38 | { 39 | let phi = 1.618; 40 | } 41 | // error: unresolved name `phi`. 42 | // println!("The value of phi is {}", phi); 43 | 44 | // let m = return_magician(); 45 | // println!("{} has {}", m.name, m.power); 46 | 47 | let mag = MagicNumber {value: 42}; 48 | let mag2 = mag; 49 | let mag3 = mag.clone(); 50 | println!("{:?}", mag); 51 | println!("{:?}", mag2); 52 | // mag, mag2 and mag3 are 3 different objects: their addresses are different: 53 | println!("{:?}", &mag as *const MagicNumber); // address is 0x23fb38 54 | println!("{:?}", &mag2 as *const MagicNumber); // address is 0x23fb30 55 | println!("{:?}", &mag3 as *const MagicNumber); // address is 0x23fb28 56 | } 57 | 58 | fn life(m: u32) -> u32 { 59 | let o = m; 60 | o 61 | } 62 | 63 | fn transform<'a>(s: &'a str) { /* ... */ } 64 | fn transform_without_lifetime(s: &str) { /* ... */ } 65 | 66 | // fn return_magician<'a>() -> &'a Magician { 67 | // let mag = Magician { name: "Gandalf", power: 4625}; 68 | // &mag // error: `mag` does not live long enough 69 | // } 70 | 71 | // The value of n2 is 42, the same as n 72 | // MagicNumber { value: 42 } 73 | // MagicNumber { value: 42 } 74 | // 0x23fb38 75 | // 0x23fb30 76 | // 0x23fb28 -------------------------------------------------------------------------------- /Chapter 6/Codes/Ownership1/Ownership1.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | 6fb08479-3950-4646-bebb-994e1653ef42 7 | exe 8 | Ownership1 9 | Ownership1 10 | Ownership1 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 6/Codes/Ownership1/src/main.rs: -------------------------------------------------------------------------------- 1 | struct Alien { 2 | planet: String, 3 | n_tentacles: u32 4 | } 5 | 6 | fn main() { 7 | let mut klaatu = Alien{ planet: "Venus".to_string(), n_tentacles: 15 }; 8 | 9 | // a move of the resource: 10 | // let kl2 = klaatu; 11 | // println!("{}", klaatu.planet); // use of moved value 'klaatu.planet' 12 | 13 | // a borrowing of the resource: 14 | let kl2 = &mut klaatu; 15 | kl2.n_tentacles = 14; 16 | println!("{} - {}", kl2.planet, kl2.n_tentacles); // Venus - 14 17 | 18 | // ownership is transferred, original owner cannot access or change: 19 | // error: cannot assign to `klaatu.planet` because it is borrowed 20 | // klaatu.planet = "Pluto".to_string(); 21 | // error: cannot borrow `klaatu.planet` as immutable because `klaatu` is also borrowed as mutable 22 | // println!("{} - {}", klaatu.planet, klaatu.n_tentacles); 23 | } -------------------------------------------------------------------------------- /Chapter 6/Codes/Ownership2/Ownership2.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | 813ad3c2-ed02-493a-916b-e801fac3549a 7 | exe 8 | Ownership2 9 | Ownership2 10 | Ownership2 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 6/Codes/Ownership2/src/main.rs: -------------------------------------------------------------------------------- 1 | struct Alien { 2 | planet: String, 3 | n_tentacles: u32, 4 | } 5 | 6 | fn main() { 7 | let mut klaatu = Alien{ planet: "Venus".to_string(), n_tentacles: 15 }; 8 | 9 | { 10 | let kl2 = &mut klaatu; 11 | kl2.n_tentacles = 14; 12 | println!("{} - {}", kl2.planet, kl2.n_tentacles); // Venus - 14 13 | kl2.n_tentacles = 10; 14 | } 15 | 16 | println!("{} - {}", klaatu.planet, klaatu.n_tentacles); // Venus - 10 17 | klaatu.planet = "Pluto".to_string(); 18 | println!("{} - {}", klaatu.planet, klaatu.n_tentacles); // Pluto - 10 19 | } -------------------------------------------------------------------------------- /Chapter 6/Codes/Ref/Ref.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | 3ea32516-3200-4ed5-99c7-d32eec5a73d0 7 | exe 8 | Ref 9 | Ref 10 | Ref 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 6/Codes/Ref/src/main.rs: -------------------------------------------------------------------------------- 1 | struct Magician { 2 | name: &'static str, 3 | power: u32 4 | } 5 | 6 | fn main() { 7 | let n = 42; 8 | match n { 9 | ref r => println!("Got a reference to {}", r), 10 | } 11 | 12 | let mut m = 42; 13 | match m { 14 | ref mut mr => { 15 | println!("Got a mutable reference to {}", mr); 16 | *mr = 43; 17 | }, 18 | } 19 | println!("m has changed to {}!", m); 20 | 21 | let mag = Magician { name: "Gandalf", power: 4625 }; 22 | let name = { 23 | // `ref_to_x` is a reference to the `x` field of `point` 24 | let Magician { name: ref ref_to_name, power: _ } = mag; 25 | // Return a copy of the `name` field of `mag` 26 | *ref_to_name 27 | }; 28 | println!("The magician's name is {}", name); 29 | } 30 | // Got a reference to 42 31 | // Got a mutable reference to 42 32 | // m has changed to 43! 33 | // The magician's name is Gandalf -------------------------------------------------------------------------------- /Chapter 6/Codes/RefCount/RefCount.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | 8dacebc9-590e-4270-a412-6b686806e298 7 | exe 8 | RefCount 9 | RefCount 10 | RefCount 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 6/Codes/RefCount/src/main.rs: -------------------------------------------------------------------------------- 1 | use std::rc::Rc; 2 | 3 | #[derive(Debug)] 4 | struct Alien { 5 | name: String, 6 | n_tentacles: u8 7 | } 8 | 9 | #[derive(Debug)] 10 | struct Tentacle { 11 | poison: u8, 12 | owner: Rc 13 | } 14 | 15 | fn main() { 16 | let dhark = Alien { name: "Dharkalen".to_string(), n_tentacles: 7 }; 17 | 18 | let dhark_master = Rc::new(dhark); 19 | 20 | for i in 1u8..dhark_master.n_tentacles { 21 | // the clone() here copies the Rc pointer, not the Alien struct: 22 | let t = Tentacle { poison: i * 3, owner: dhark_master.clone() }; 23 | println!("{:?}", t); 24 | } 25 | } 26 | // Tentacle { poison: 3, owner: Alien { name: "Dharkalen", n_tentacles: 7 } } 27 | // Tentacle { poison: 6, owner: Alien { name: "Dharkalen", n_tentacles: 7 } } 28 | // Tentacle { poison: 9, owner: Alien { name: "Dharkalen", n_tentacles: 7 } } 29 | // Tentacle { poison: 12, owner: Alien { name: "Dharkalen", n_tentacles: 7 } } 30 | // Tentacle { poison: 15, owner: Alien { name: "Dharkalen", n_tentacles: 7 } } 31 | // Tentacle { poison: 18, owner: Alien { name: "Dharkalen", n_tentacles: 7 } } -------------------------------------------------------------------------------- /Chapter 6/Codes/RefCountNotgood/RefCountNotgood.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | fae880ee-f103-4f43-b3db-43944a9754d5 7 | exe 8 | RefCountNotgood 9 | RefCountNotgood 10 | RefCountNotgood 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 6/Codes/RefCountNotgood/src/main.rs: -------------------------------------------------------------------------------- 1 | // this program DOES NOT COMPILE: on purpose 2 | struct Alien { 3 | name: String, 4 | no_tentacles: u8 5 | } 6 | 7 | struct Tentacle { 8 | poison: u8, 9 | owner: Alien 10 | } 11 | 12 | fn main() { 13 | let dhark = Alien { name: "Dharkalen".to_string(), no_tentacles: 7 }; 14 | 15 | // defining dhark's tentacles: 16 | for i in 1u8..dhark.no_tentacles { 17 | // error in following line: 18 | // use of moved value 'dhark' 19 | // note: `dhark` moved here because it has type `Alien`, which is non-copyable 20 | Tentacle { poison: i * 3, owner: dhark }; 21 | } 22 | } -------------------------------------------------------------------------------- /Chapter 6/Codes/References/References.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | 78630dbd-1bd6-4173-a02c-8cd041f38fd5 7 | exe 8 | References 9 | References 10 | References 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 6/Codes/References/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | // immutable reference to immutable values: 3 | let n = 42i32; 4 | 5 | // a reference to n: 6 | let m = &n; 7 | println!("The address of n is {:p}", m); 8 | println!("The value of n is {}", *m); 9 | println!("The value of n is {}", m); 10 | 11 | // references to immutable values are immutable: 12 | // *m = 7; // error: cannot assign to immutable borrowed content `*m` 13 | 14 | // multiple referencesto an immutable value: 15 | let o = &n; 16 | println!("The address of n is {:p}", o); 17 | println!("The value of n is {}", *o); 18 | 19 | // a mutable reference to an immutable value is not possible: 20 | // let m = &mut n; // error: cannot borrow immutable local variable `n` as mutable 21 | 22 | // references to mutable values: 23 | let mut u = 3.14f64; 24 | let v = &mut u; 25 | println!("The address of u is {:p}", v); 26 | println!("The value of u is {}", *v); 27 | *v = 3.15; 28 | println!("The value of u is now {}", *v); 29 | // error: cannot borrow `u` as immutable because it is also borrowed as mutable 30 | // println!("The value of u is {}", u); 31 | // u = u * 2.0; // error: cannot assign to `u` because it is borrowed 32 | 33 | // more than 1 mutable reference is not allowed: 34 | // let w = &mut u; // error: cannot borrow `u` as mutable more than once at a time 35 | 36 | // change a value by passing it as a reference to a function: 37 | let mut m = 7; 38 | add_three_to_magic(&mut m); 39 | println!("{}", m); // 10 40 | } 41 | 42 | fn add_three_to_magic(num: &mut i32) { 43 | *num += 3; // value is changed in place with +=, is same as: *num = *num + 3 44 | } 45 | // The address of n is 0x23fbe4 46 | // The value of n is 42 47 | // The value of n is 42 48 | // The address of n is 0x23fbe4 49 | // The value of n is 42 50 | // The address of u is 0x23f8d0 51 | // The value of u is 3.14 52 | // The value of u is now 3.15 53 | // 10 -------------------------------------------------------------------------------- /Chapter 6/Exercises/DanglingPointer/DanglingPointer.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | f6220dee-da0b-4de6-81ae-312ec0e47853 7 | exe 8 | DanglingPointer 9 | DanglingPointer 10 | DanglingPointer 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 6/Exercises/DanglingPointer/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | // n does not live long enough to be assigned to m 3 | // let m: &u32 = { 4 | // let n = &5u32; // error: borrowed value does not live long enough 5 | // n 6 | // }; 7 | // let o = *m; 8 | 9 | // The following will be rejected, since y has a shorter lifetime than x. 10 | let mut x = &3; 11 | { 12 | let mut y = 4; 13 | // x = &y; // error: `y` does not live long enough 14 | } // y is freed here, but x still lives... 15 | } -------------------------------------------------------------------------------- /Chapter 6/Exercises/GrowTentacle/GrowTentacle.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | 26aacaa2-d861-49ac-a055-5bc060d08cf4 7 | exe 8 | GrowTentacle 9 | GrowTentacle 10 | GrowTentacle 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 6/Exercises/GrowTentacle/src/main.rs: -------------------------------------------------------------------------------- 1 | struct Alien { 2 | planet: String, 3 | no_tentacles: u32, 4 | } 5 | 6 | fn main() { 7 | let mut klaatu = Alien{ planet: "Venus".to_string(), no_tentacles: 15 }; 8 | println!("Klaatu first has {} tentacles", klaatu.no_tentacles); // 15 9 | grow_a_tentacle(&mut klaatu); 10 | println!("Klaatu has now {} tentacles", klaatu.no_tentacles); // 16 11 | } 12 | 13 | fn grow_a_tentacle(al: &mut Alien) { 14 | al.no_tentacles += 1; 15 | } // al goes out of scope 16 | 17 | // Klaatu has first 15 tentacles 18 | // Klaatu has now 16 tentacles -------------------------------------------------------------------------------- /Chapter 6/Exercises/Ownership3/Ownership3.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | a1d4a55f-1a91-4fac-a240-9a7f0c35fdd5 7 | exe 8 | Ownership3 9 | Ownership3 10 | Ownership3 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 6/Exercises/Ownership3/src/main.rs: -------------------------------------------------------------------------------- 1 | struct Alien { 2 | planet: String, 3 | no_tentacles: u32, 4 | } 5 | 6 | fn main() { 7 | let mut klaatu = Alien{ planet: "Venus".to_string(), no_tentacles: 15 }; 8 | 9 | // Question 1) 10 | let kl2 = &klaatu; 11 | // error: cannot assign to immutable field `kl2.no_tentacles` 12 | // kl2.no_tentacles = 14; 13 | println!("{} - {}", kl2.planet, kl2.no_tentacles); // Venus - 15 14 | 15 | // error: cannot assign to `klaatu.planet` because it is borrowed 16 | // klaatu.planet = "Pluto".to_string(); 17 | println!("{} - {}", klaatu.planet, klaatu.no_tentacles); // Venus - 15 18 | 19 | // Question 2) - with the following statement: 20 | // let klaatuc = klaatu; 21 | // let kl2 = &klaatu; 22 | // we get the following error at the kl2 binding: 23 | // error: use of moved value: `klaatu` 24 | // `klaatu` moved here (line 10: let klaatuc = klaatu;) because it has type `Alien`, 25 | // which is moved by default 26 | 27 | // mutability can be changed when ownership is transferred: 28 | let im = Box::new(7u32); 29 | // Mutability error: 30 | // error: cannot assign to immutable `Box` content `*im` 31 | // *im = 4; 32 | // Hand over the box, changing mutability 33 | let mut muta = im; 34 | println!("muta contains {}", muta); 35 | // println!("im contains {}", im); // error: use of moved value `im` 36 | // Modify the contents of the box 37 | *muta = 42; 38 | println!("muta now contains {}", muta); 39 | } 40 | // Venus - 15 41 | // Venus - 15 42 | // muta contains 7 43 | // muta now contains 42 -------------------------------------------------------------------------------- /Chapter 7/Codes/Cube/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "cube" 3 | version = "0.0.1" 4 | authors = ["Ivo Balbaert "] 5 | -------------------------------------------------------------------------------- /Chapter 7/Codes/Cube/Cube.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | 5b83a30b-48e4-456e-bc56-ee107a6e20f1 7 | exe 8 | Cube 9 | Cube 10 | Cube 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 7/Codes/Cube/src/lib.rs: -------------------------------------------------------------------------------- 1 | #[cfg(test)] 2 | mod test; 3 | 4 | pub fn cube(val: u32) -> u32 { 5 | // implementation goes here 6 | val * val * val 7 | } -------------------------------------------------------------------------------- /Chapter 7/Codes/Cube/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | println!("Hello, world!") 3 | } -------------------------------------------------------------------------------- /Chapter 7/Codes/Cube/src/test.rs: -------------------------------------------------------------------------------- 1 | // test module in a different file test.rs: 2 | use super::*; 3 | 4 | #[test] 5 | fn cube_of_2_is_8() { 6 | assert_eq!(cube(2), 8); 7 | } 8 | 9 | // other test functions: 10 | // ... -------------------------------------------------------------------------------- /Chapter 7/Codes/Cube/tests/lib.rs: -------------------------------------------------------------------------------- 1 | extern crate cube; 2 | // use cube::cube; 3 | 4 | #[test] 5 | fn cube_of_4_is_64() { 6 | assert_eq!(cube::cube(4), 64); 7 | } 8 | 9 | // other test functions: 10 | // ... -------------------------------------------------------------------------------- /Chapter 7/Codes/ImportModules/ImportModules.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | f37a4e41-eee6-480f-bdb3-8cc26a969931 7 | exe 8 | ImportModules 9 | ImportModules 10 | ImportModules 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 7/Codes/ImportModules/src/main.rs: -------------------------------------------------------------------------------- 1 | mod modul1; 2 | mod modul2; 3 | 4 | // use modul1::func1; 5 | 6 | fn main() { 7 | modul1::func1(); 8 | modul2::func1(); 9 | 10 | // func1(); // error: unresolved name `func1` 11 | // func1(); // works when use modul1::func1; is added 12 | } 13 | // called func1 from modul1 14 | // called func1 from modul2 -------------------------------------------------------------------------------- /Chapter 7/Codes/ImportModules/src/modul1/mod.rs: -------------------------------------------------------------------------------- 1 | pub fn func1() { 2 | println!("called func1 from modul1"); 3 | } 4 | -------------------------------------------------------------------------------- /Chapter 7/Codes/ImportModules/src/modul2.rs: -------------------------------------------------------------------------------- 1 | pub fn func1() { 2 | println!("called func1 from modul2"); 3 | } -------------------------------------------------------------------------------- /Chapter 7/Codes/Macros/Macros.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | f4960ef6-06eb-40eb-bd0f-6dac947af889 7 | exe 8 | Macros 9 | Macros 10 | Macros 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 7/Codes/Macros/src/main.rs: -------------------------------------------------------------------------------- 1 | macro_rules! welcome { 2 | // `()` indicates that the macro takes no argument 3 | () => ( 4 | // the macro will expand into the contents of this block 5 | println!("Welcome to the Game!"); 6 | ) 7 | } 8 | 9 | macro_rules! mac1 { 10 | ($arg:expr) => (println!("arg is {}", $arg)); 11 | } 12 | 13 | macro_rules! printall { 14 | ( $( $arg:expr ), * ) => ( {$( print!("{} / ", $arg) ); *} ); 15 | } 16 | 17 | macro_rules! create_fn { 18 | ($fname:ident) => ( 19 | fn $fname() { 20 | println!("Called the function {:?}()", stringify!($fname)) 21 | } 22 | ) 23 | } 24 | 25 | create_fn!(fn1); 26 | 27 | macro_rules! massert { 28 | ($arg:expr) => ( 29 | if $arg {} 30 | else { panic!("Assertion failed!"); } 31 | ); 32 | } 33 | 34 | macro_rules! unless { 35 | ($arg:expr, $branch:expr) => ( if !$arg { $branch }; ); 36 | } 37 | 38 | macro_rules! test_eq { 39 | ($name:ident, $left:expr, $right:expr) => { 40 | #[test] 41 | fn $name() { 42 | assert_eq!($left, $right); 43 | } 44 | } 45 | } 46 | 47 | test_eq!(seven_times_six_is_forty_two, 7 * 6, 42); 48 | test_eq!(seven_times_six_is_not_forty_three, 7 * 6, 43); 49 | 50 | fn main() { 51 | welcome!(); // Welcome to the Game! 52 | mac1!(42); // arg is 42 53 | printall!("hello", 42, 3.14); // hello / 42 / 3.14 / 54 | fn1(); 55 | // massert!(1 == 42); 56 | 57 | let v = [10, 40, 30]; 58 | massert!(v.contains(&30)); 59 | massert!(!v.contains(&50)); 60 | unless!(v.contains(&25), println!("v does not contain 25")); 61 | 62 | } 63 | // Welcome to the Game! 64 | // arg is 42 65 | // hello / 42 / 3.14 / Called the function "fn1"() 66 | // thread '
' panicked at 'Assertion failed!' 67 | // v does not contain 25 -------------------------------------------------------------------------------- /Chapter 7/Codes/Modules/Modules.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | ff9a90cc-7802-4e62-a22a-bedab5b1973c 7 | exe 8 | Modules 9 | Modules 10 | Modules 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 7/Codes/Modules/src/main.rs: -------------------------------------------------------------------------------- 1 | use game1::func2; 2 | use game1::func2 as gf2; 3 | // use game1::{func2, func3}; 4 | // use game1::*; 5 | use game1::subgame1::subfunc1 as sf1; 6 | 7 | mod game1 { 8 | // all of the module's code items go in here 9 | fn func1() { // private function 10 | println!("Am I visible?"); 11 | } 12 | 13 | pub fn func2() { 14 | println!("You called func2 in game1!"); 15 | } 16 | 17 | pub fn func3() { 18 | println!("You called func2 in game1!"); 19 | } 20 | 21 | pub mod subgame1 { 22 | pub fn subfunc1() { 23 | println!("You called subfunc1 in subgame1!"); 24 | } 25 | } 26 | 27 | pub struct Magician { 28 | pub name: String, 29 | pub age: i32, 30 | power: i32 31 | } 32 | } 33 | 34 | fn main() { 35 | // game1::func1(); // error: function `func1` is private 36 | game1::func2(); // works without the use import 37 | 38 | // calling a nested module: 39 | game1::subgame1::subfunc1(); 40 | 41 | // importing a function or module with use: 42 | func2(); 43 | gf2(); 44 | sf1(); 45 | 46 | // error: field `power` of struct `game1::Magician` is private 47 | // let mag1 = game1::Magician { name: "Gandalf".to_string(), age: 725, power: 98}; 48 | } 49 | 50 | // You called func2 in game1! 51 | // You called subfunc1 in subgame1! 52 | // You called func2 in game1! 53 | // You called func2 in game1! 54 | // You called subfunc1 in subgame1! -------------------------------------------------------------------------------- /Chapter 7/Codes/Monsters/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | 3 | name = "monsters" 4 | version = "0.0.1" 5 | authors = ["Ivo Balbaert "] 6 | 7 | [dependencies] 8 | log = "0.3.1" 9 | mac = "*" -------------------------------------------------------------------------------- /Chapter 7/Codes/Monsters/Monsters.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | 3531234a-0e96-4691-a806-0d1749bb7e92 7 | exe 8 | Monsters 9 | Monsters 10 | Monsters 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 7/Codes/Monsters/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub fn print_from_monsters() { 2 | println!("Printing from crate monsters!"); 3 | } 4 | 5 | pub trait Monster { 6 | fn new(hlt: u32, dam: u32) -> Self; 7 | 8 | fn attack(&self); 9 | fn noise(&self) -> &'static str; 10 | 11 | fn attacks_with_sound(&self) { 12 | println!("The Monster attacks by making an awkward sound {}", self.noise()); 13 | } 14 | } 15 | 16 | #[derive(Debug)] 17 | pub struct Zombie { pub health: u32, pub damage: u32 } 18 | 19 | impl Monster for Zombie { 20 | fn new(mut h: u32, d: u32) -> Zombie { 21 | // constraints: 22 | if h > 100 { h = 100; } 23 | Zombie {health: h, damage: d} 24 | } 25 | 26 | fn attack(&self) { 27 | println!("The Zombie bites! Your health lowers with {} damage points.", 2 * self.damage); 28 | } 29 | 30 | fn noise(&self) -> &'static str { 31 | "Aaargh!" 32 | } 33 | } 34 | 35 | struct Alien { health: u32, damage: u32 } 36 | 37 | impl Monster for Alien { 38 | fn new(mut h: u32, d: u32) -> Alien { 39 | // constraints: 40 | if h > 100 { h = 100; } 41 | Alien {health: h, damage: d} 42 | } 43 | 44 | fn attack(&self) { 45 | println!("I attack! Your health lowers with {} damage points.", self.damage); 46 | } 47 | 48 | fn noise(&self) -> &'static str { 49 | "Shriek!" 50 | } 51 | } 52 | 53 | struct Predator { health: u32, damage: u32 } 54 | // Predator still has to implement new and noise methods: 55 | // impl Monster for Predator { 56 | // fn attack(&self) { 57 | // println!("I bite you! Your health lowers with {} damage points.", 3 * self.damage); 58 | // } 59 | // } -------------------------------------------------------------------------------- /Chapter 7/Codes/Monsters/src/main.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate log; 3 | extern crate mac; 4 | 5 | extern crate monsters; 6 | use monsters::Monster; // import the trait 7 | 8 | fn main() { 9 | monsters::print_from_monsters(); 10 | let zmb1 = monsters::Zombie {health: 75, damage: 15}; 11 | println!("Oh no, I hear: {}", zmb1.noise()); 12 | zmb1.attack(); 13 | println!("{:?}", zmb1); 14 | 15 | info!("Gathering information from monster {:?}", zmb1); 16 | } 17 | // Printing from crate monsters! 18 | // Oh no, I hear: Aaargh! 19 | // The Zombie bites! Your health lowers with 30 damage points. 20 | // Zombie { health: 75, damage: 15 } -------------------------------------------------------------------------------- /Chapter 7/Codes/Structs/Structs.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | 1cf5e6a0-e30c-4989-b6e6-439b2c0e1552 7 | exe 8 | Structs 9 | Structs 10 | Structs 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 7/Codes/Structs/src/main.rs: -------------------------------------------------------------------------------- 1 | #![crate_type = "lib"] 2 | #![crate_name = "mycrate"] 3 | 4 | struct Player { 5 | nname: &'static str, // nickname 6 | health: i32, 7 | level: u8 8 | } 9 | 10 | fn main() { 11 | struct Scoreu; // unit struct 12 | 13 | // tuple structs: 14 | struct Score(i32, u8); 15 | let score1 = Score(73, 2); // make (instantiate) a tuple struct 16 | let Score(h, l) = score1; // // extract values by destructuring 17 | println!("Health {} - Level {}", h, l); 18 | 19 | // newtype: 20 | struct Kilograms(u32); 21 | let weight = Kilograms(250); 22 | let Kilograms(kgm) = weight; // extracting kgm 23 | println!("weight is {} kilograms", kgm); 24 | 25 | // struct: 26 | let mut pl1 = Player{nname: "Dzenan", health: 73, level: 2}; 27 | println!("Player {} is at level {}", pl1.nname, pl1.level); 28 | pl1.level = 3; 29 | 30 | // pointers do automatic dereferencing when accessing data structure elements: 31 | let ps = &Player{ nname: "John", health: 95, level: 1 }; 32 | println!("{} == {}", ps.nname, (*ps).nname); 33 | 34 | // destructuring a struct: 35 | let Player{health: ht, nname: nn, ..} = pl1; 36 | println!("Player {} has health {}", nn, ht); 37 | } 38 | // Health 73 - Level 2 39 | // weight is 250 kilograms 40 | // Player Dzenan is at level 2 41 | // John == John 42 | // Player Dzenan has health 73 -------------------------------------------------------------------------------- /Chapter 7/Exercises/MacroEx/MacroEx.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | 89e6c70a-ca79-4576-b249-ad380d27d5cb 7 | exe 8 | MacroEx 9 | MacroEx 10 | MacroEx 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 7/Exercises/MacroEx/src/main.rs: -------------------------------------------------------------------------------- 1 | macro_rules! mac2 { 2 | ($arg:expr) => (3 * $arg); 3 | } 4 | 5 | macro_rules! mac3 { 6 | ($arg:ident) => (let $arg = 42); 7 | } 8 | 9 | macro_rules! mac4 { 10 | ($arg:expr) => ( { 11 | print!("start - "); 12 | print!("{} - ", $arg); 13 | print!("end"); 14 | }); 15 | } 16 | 17 | fn main() { 18 | println!("{}", mac2!(5)); // 15 19 | println!("{}", mac2!(2 + 3)); // 15 20 | mac3!(x); // expands into let x = 42; 21 | println!("{}", x); // 42 22 | mac4!("Where am I?"); // start - Where am I? - end 23 | } -------------------------------------------------------------------------------- /Chapter 7/Exercises/PrivStruct/PrivStruct.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | ec99632c-032a-45d2-a18a-2697b5d7feec 7 | exe 8 | PrivStruct 9 | PrivStruct 10 | PrivStruct 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 7/Exercises/PrivStruct/src/main.rs: -------------------------------------------------------------------------------- 1 | use game1::Magician; 2 | 3 | mod game1 { 4 | #[derive(Debug)] 5 | pub struct Magician { 6 | pub name: String, 7 | pub age: i32, 8 | power: i32 9 | } 10 | 11 | impl Magician { 12 | // A public constructor 13 | pub fn new(nm: String, ag: i32, pow: i32) -> Magician { 14 | Magician { name: nm, age: ag, power: pow} 15 | } 16 | } 17 | } 18 | 19 | fn main() { 20 | // error: field `power` of struct `game1::Magician` is private 21 | // let mag1 = game1::Magician { name: "Gandalf", age: 725, power: 98}; 22 | 23 | let mag1 = Magician::new("Gandalf".to_string(), 725, 98); 24 | println!("I just made a magician {:?}", mag1); 25 | } 26 | // I just made a magician Magician { name: "Gandalf", age: 725, power: 98 } -------------------------------------------------------------------------------- /Chapter 8/Codes/Channels/Channels.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | 3307c506-0964-45bc-8116-125a725f128c 7 | exe 8 | Channels 9 | Channels 10 | Channels 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 8/Codes/Channels/src/main.rs: -------------------------------------------------------------------------------- 1 | use std::thread; 2 | use std::sync::mpsc::channel; 3 | // use std::sync::mpsc::{Sender, Receiver}; 4 | 5 | fn main() { 6 | // let (tx, rx): (Sender, Receiver) = mpsc::channel(); 7 | let (tx, rx) = channel(); 8 | 9 | thread::spawn(move|| { 10 | // tx.send(10).unwrap(); 11 | tx.send(10).ok().expect("Unable to send message"); 12 | }); 13 | 14 | let res = rx.recv().unwrap(); 15 | println!("{:?}", res); // 10 16 | } 17 | // 10 -------------------------------------------------------------------------------- /Chapter 8/Codes/Channels2/Channels2.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | fa334d76-f07d-4476-a72a-4c215cbf8c6c 7 | exe 8 | Channels2 9 | Channels2 10 | Channels2 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 8/Codes/Channels2/src/main.rs: -------------------------------------------------------------------------------- 1 | use std::thread; 2 | use std::sync::mpsc::channel; 3 | 4 | fn main() { 5 | let (tx, rx) = channel(); 6 | 7 | thread::spawn(move|| { 8 | let result = some_expensive_computation(); 9 | tx.send(result).ok().expect("Unable to send message"); 10 | }); 11 | 12 | some_other_expensive_computation(); 13 | let result = rx.recv(); 14 | println!("{:?}", result); // Ok(1) 15 | } 16 | 17 | fn some_expensive_computation() -> i32 { 1 } 18 | fn some_other_expensive_computation() { } -------------------------------------------------------------------------------- /Chapter 8/Codes/MakeChannel/MakeChannel.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | 16df100e-ec63-42f7-b766-3f8e13b9375d 7 | exe 8 | MakeChannel 9 | MakeChannel 10 | MakeChannel 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 8/Codes/MakeChannel/src/main.rs: -------------------------------------------------------------------------------- 1 | use std::sync::mpsc::Receiver; 2 | use std::sync::mpsc::channel; 3 | 4 | fn make_chan() -> Receiver { 5 | let (tx, rx) = channel(); 6 | tx.send(7).unwrap(); 7 | rx 8 | } 9 | 10 | fn main() { 11 | let rx = make_chan(); 12 | if let Some(msg) = rx.recv().ok() { 13 | println!("received message {}", msg); 14 | }; 15 | } 16 | // received message 7 -------------------------------------------------------------------------------- /Chapter 8/Codes/ManyThreads/ManyThreads.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | 22bb49a4-e75c-4771-be61-fb922d02d424 7 | exe 8 | ManyThreads 9 | ManyThreads 10 | ManyThreads 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 8/Codes/ManyThreads/src/main.rs: -------------------------------------------------------------------------------- 1 | use std::thread; 2 | 3 | static NTHREADS: i32 = 10000; 4 | 5 | fn main() { 6 | for i in 0..NTHREADS { 7 | thread::spawn(move || { 8 | println!("this is thread number {}", i) 9 | }); 10 | } 11 | } -------------------------------------------------------------------------------- /Chapter 8/Codes/ManyThreads2/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "many_threads" 3 | version = "0.1.0" 4 | authors = ["Ivo Balbaert "] 5 | 6 | [dependencies] 7 | num_cpus = "*" 8 | threadpool = "*" 9 | 10 | -------------------------------------------------------------------------------- /Chapter 8/Codes/ManyThreads2/ManyThreads2.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | ed94032e-5b69-4704-b93d-a3bd819a34cb 7 | exe 8 | ManyThreads2 9 | ManyThreads2 10 | ManyThreads2 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 8/Codes/ManyThreads2/src/main.rs: -------------------------------------------------------------------------------- 1 | extern crate num_cpus; 2 | extern crate threadpool; 3 | 4 | use std::thread; 5 | use threadpool::ThreadPool; 6 | 7 | fn main() { 8 | let ncpus = num_cpus::get(); 9 | println!("The number of cpus in this machine is: {}", ncpus); 10 | 11 | let pool = ThreadPool::new(ncpus); 12 | 13 | for i in 0..ncpus { 14 | pool.execute(move || { 15 | println!("this is thread number {}", i) 16 | }); 17 | } 18 | 19 | thread::sleep_ms(50); 20 | } 21 | // this is thread number 0 22 | // this is thread number 5 23 | // this is thread number 7 24 | // this is thread number 3 25 | // this is thread number 4 26 | // this is thread number 1 27 | // this is thread number 6 28 | // this is thread number 2 -------------------------------------------------------------------------------- /Chapter 8/Codes/NotShared/NotShared.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | 66cea022-3b97-4b56-a08f-d9b8885c6a2b 7 | exe 8 | NotShared 9 | NotShared 10 | NotShared 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 8/Codes/NotShared/src/main.rs: -------------------------------------------------------------------------------- 1 | use std::thread; 2 | 3 | fn main() { 4 | let mut health = 12; 5 | for i in 2..5 { 6 | thread::spawn(move || { 7 | health *= i; 8 | }); 9 | } 10 | thread::sleep_ms(2000); 11 | println!("{}", health); // 12 12 | } -------------------------------------------------------------------------------- /Chapter 8/Codes/PanicThread/PanicThread.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | a3721d32-7e9c-4734-934d-407604b2f73c 7 | exe 8 | PanicThread 9 | PanicThread 10 | PanicThread 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 8/Codes/PanicThread/src/main.rs: -------------------------------------------------------------------------------- 1 | use std::thread; 2 | 3 | fn main() { 4 | let result = thread::spawn(move || { 5 | panic!("I have fallen into an unrecoverable trap!"); 6 | }).join(); 7 | 8 | if result.is_err() { 9 | println!("This child has panicked"); 10 | } 11 | } 12 | // thread '' panicked at 'I have fallen into an unrecoverable trap!', F:\Rust\programs\concurrency\panic_thread.rs:5 13 | // This child has panicked 14 | -------------------------------------------------------------------------------- /Chapter 8/Codes/SyncChannel/SyncChannel.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | fa4722f0-6f04-49ff-9181-433b3ec81512 7 | exe 8 | SyncChannel 9 | SyncChannel 10 | SyncChannel 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 8/Codes/SyncChannel/src/main.rs: -------------------------------------------------------------------------------- 1 | use std::sync::mpsc::sync_channel; 2 | use std::thread; 3 | 4 | type TokenType = i32; 5 | 6 | struct Msg { 7 | typ: TokenType, 8 | val: String, 9 | } 10 | 11 | fn main() { 12 | let (tx, rx) = sync_channel(1); // buffer size 1 13 | tx.send(Msg {typ: 42, val: "Rust is cool".to_string()}).unwrap(); 14 | println!("message 1 is sent"); 15 | thread::spawn(move|| { 16 | tx.send(Msg {typ: 43, val: "Rust is still cool".to_string()}).unwrap(); 17 | println!("message 2 is sent"); 18 | }); 19 | 20 | println!("Waiting for 3 seconds ..."); 21 | thread::sleep_ms(3000); 22 | 23 | if let Some(msg) = rx.recv().ok() { 24 | println!("received message of type {} and val {}", msg.typ, msg.val); 25 | }; 26 | if let Some(msg) = rx.recv().ok() { 27 | println!("received second message of type {} and val {}", msg.typ, msg.val); 28 | }; 29 | } 30 | // message 1 is sent 31 | // Waiting for 3 seconds ... 32 | // received message of type 42 and val Rust is cool 33 | // message 2 is sent 34 | // received second message of type 43 and val Rust is still cool 35 | -------------------------------------------------------------------------------- /Chapter 8/Codes/ThreadSafe/ThreadSafe.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | 8de4e820-ea8d-4e8c-aafd-c3130c1b8335 7 | exe 8 | ThreadSafe 9 | ThreadSafe 10 | ThreadSafe 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 8/Codes/ThreadSafe/src/main.rs: -------------------------------------------------------------------------------- 1 | use std::thread; 2 | use std::sync::{Arc, Mutex}; 3 | 4 | fn main() { 5 | let mut health = 12; 6 | println!("health before: {:?}", health); 7 | let data = Arc::new(Mutex::new(health)); 8 | for i in 2..5 { 9 | let mutex = data.clone(); 10 | thread::spawn(move || { 11 | let health = mutex.lock(); 12 | match health { 13 | // health is multiplied by i: 14 | Ok(mut health) => *health *= i, 15 | Err(str) => println!("{}", str) 16 | } 17 | }).join().unwrap(); 18 | }; 19 | health = *data.lock().unwrap(); 20 | println!("health after: {:?}", health); 21 | } 22 | // health before: 12 23 | // health after: 288 24 | // because: 288 = 12 * 2 * 3 * 4 -------------------------------------------------------------------------------- /Chapter 8/Codes/ThreadSpawn/ThreadSpawn.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | 1d120746-5a51-4ef3-9fe4-3f024d97fb4d 7 | exe 8 | ThreadSpawn 9 | ThreadSpawn 10 | ThreadSpawn 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 8/Codes/ThreadSpawn/src/main.rs: -------------------------------------------------------------------------------- 1 | use std::thread; 2 | 3 | fn main() { 4 | let handle = thread::spawn(move || { 5 | println!("Hello from the goblin in the spawned thread!"); 6 | }); 7 | 8 | // thread::sleep_ms(50); 9 | 10 | // do other work in the meantime 11 | let output = handle.join().unwrap(); // () 12 | println!("{:?}", output); 13 | 14 | // if no other work has to be done: 15 | thread::spawn(move || { 16 | println!("Hello again from the goblin in the spawned thread!"); 17 | // other work done in child thread 18 | }).join(); 19 | } 20 | // Hello from the goblin in the spawned thread! 21 | // () 22 | // Hello again from the goblin in the spawned thread! 23 | -------------------------------------------------------------------------------- /Chapter 8/Exercises/SharedChannel/SharedChannel.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | 1825156b-62ee-43b9-8d32-3bbaee450810 7 | exe 8 | SharedChannel 9 | SharedChannel 10 | SharedChannel 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 8/Exercises/SharedChannel/src/main.rs: -------------------------------------------------------------------------------- 1 | use std::thread; 2 | use std::sync::mpsc; 3 | 4 | static NTHREADS: usize = 7; 5 | 6 | fn main() { 7 | let (tx, rx) = mpsc::channel(); 8 | 9 | for id in 0..NTHREADS { 10 | let thread_tx = tx.clone(); // clone the sender end-point 11 | thread::spawn(move || { 12 | thread_tx.send(id).unwrap(); 13 | println!("thread {} done", id); 14 | }); 15 | } 16 | 17 | let mut ids = Vec::with_capacity(NTHREADS); 18 | for _ in 0..NTHREADS { 19 | ids.push(rx.recv().unwrap()); 20 | } 21 | 22 | println!("{:?}", ids); 23 | } 24 | // -- The order is different each time the program is run: -- 25 | // thread 0 done 26 | // thread 1 done 27 | // thread 2 done 28 | // thread 3 done 29 | // thread 5 done 30 | // thread 4 done 31 | // thread 6 done 32 | // [1, 0, 2, 3, 5, 4, 6] -------------------------------------------------------------------------------- /Chapter 9/Codes/Arguments/Arguments.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | 5f4c69ca-0370-4f2e-a987-a3433c991602 7 | exe 8 | Arguments 9 | Arguments 10 | Arguments 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 9/Codes/Arguments/src/main.rs: -------------------------------------------------------------------------------- 1 | use std::env; 2 | 3 | fn main() { 4 | // command-line arguments: 5 | let args: Vec = env::args().collect(); 6 | println!("The program's name is: {}", args[0]); 7 | for arg in args.iter() { 8 | println!("Next argument is: {}", arg) 9 | } 10 | // tail() is unstable in 1.0 Beta 2: 11 | // println!("I got {:?} arguments: {:?}.", args.len() - 1, args.tail()); 12 | println!("I got {:?} arguments: ", args.len() - 1); 13 | for n in 1..args.len() { 14 | println!("The {}th argument is {}", n, args[n]); 15 | } 16 | // slice pattern is experimental in 1.0 Beta 2 17 | // match &args[..] { 18 | // [ref progname] => { no() }, // no arguments passed 19 | // [_, ref arg1] => { one() }, // one argument passed 20 | // [_, ref arg1, ref arg2] => { two() }, // two arguments passed 21 | // _ => { help(); } // all the other cases 22 | // } 23 | 24 | // OS-environment variables: 25 | let osvars = env::vars(); 26 | for (key, value) in osvars { 27 | println!("{}: {}", key, value); 28 | } 29 | } 30 | 31 | // fn no() { println!("no arguments");} 32 | // fn one() { println!("one argument");} 33 | // fn two() { println!("two arguments"); } 34 | 35 | // fn help() { 36 | // println!("Usage: 37 | // arguments Check whether string is ok. 38 | // arguments func1 Apply func1 to integer"); 39 | // } 40 | -------------------------------------------------------------------------------- /Chapter 9/Codes/Asm/Asm.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | c7d72357-fd04-4767-a4ab-558b5d70e817 7 | exe 8 | Asm 9 | Asm 10 | Asm 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 9/Codes/Asm/src/main.rs: -------------------------------------------------------------------------------- 1 | #![feature(asm)] 2 | 3 | fn subtract(a: i32, b: i32) -> i32 { 4 | let sub: i32; 5 | unsafe { 6 | asm!("sub $2, $1; mov $1, $0" 7 | : "=r"(sub) 8 | : "r"(a), "r"(b) 9 | ); 10 | } 11 | sub 12 | } 13 | 14 | fn main() { 15 | println!("{}", subtract(42, 7)) // 35 16 | } -------------------------------------------------------------------------------- /Chapter 9/Codes/CallingCLibrary/CallingCLibrary.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | 41e683c0-30a9-4142-b386-e9779aa8a4f5 7 | exe 8 | CallingCLibrary 9 | CallingCLibrary 10 | CallingCLibrary 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 9/Codes/CallingCLibrary/src/main.rs: -------------------------------------------------------------------------------- 1 | #[repr(C)] 2 | #[derive(Copy, Clone)] 3 | #[derive(Debug)] 4 | struct Complex { 5 | re: f32, 6 | im: f32, 7 | } 8 | 9 | #[link(name = "m")] 10 | extern { 11 | fn ctanf(z: Complex) -> Complex; 12 | } 13 | 14 | fn tan(z: Complex) -> Complex { 15 | unsafe { ctanf(z) } 16 | } 17 | 18 | fn main() { 19 | let z = Complex { re: -1., im: 1. }; // z is -1 + i 20 | let z_tan = tan(z); 21 | println!("the tangens of {:?} is {:?}", z, z_tan); 22 | } 23 | // the tangens of Complex { re: -1, im: 1 } is Complex { re: -0.271753, im: 1.083923 } -------------------------------------------------------------------------------- /Chapter 9/Codes/CallingLibc/CallingLibc.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | 831b77fe-f04b-48e4-8617-abacbabc0784 7 | exe 8 | CallingLibc 9 | CallingLibc 10 | CallingLibc 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 9/Codes/CallingLibc/src/main.rs: -------------------------------------------------------------------------------- 1 | // error: use of unstable library feature 'libc' 2 | // help: add #![feature(libc)] to the crate attributes to enable 3 | #![feature(libc)] 4 | 5 | extern crate libc; 6 | use libc::puts; 7 | use std::ffi::CString; 8 | 9 | fn main() { 10 | let sentence = "Merlin is the greatest magician!"; 11 | let to_print = CString::new(sentence).unwrap(); 12 | unsafe { 13 | puts(to_print.as_ptr()); 14 | } 15 | } 16 | // Merlin is the greatest magician! -------------------------------------------------------------------------------- /Chapter 9/Codes/RawPointers/RawPointers.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | 369b03c5-871f-43f2-a339-c6e59f0e8212 7 | exe 8 | RawPointers 9 | RawPointers 10 | RawPointers 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 9/Codes/RawPointers/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | // dereferencing a raw pointer: 3 | let p_raw: *const u32 = &10; 4 | // error: dereference of unsafe pointer requires unsafe function or block [E0133] 5 | // let n = *p_raw; 6 | 7 | unsafe { 8 | // dereferencing a raw pointer must be done inside unsafe block: 9 | let n = *p_raw; 10 | println!("{}", n); // 10 11 | } 12 | 13 | // converting between references and raw pointers: 14 | let gr: f32 = 1.618; 15 | let p_imm: *const f32 = &gr as *const f32; // explicit cast 16 | let mut m: f32 = 3.14; 17 | let p_mut: *mut f32 = &mut m; // implicit coercion 18 | 19 | unsafe { 20 | let ref_imm: &f32 = &*p_imm; 21 | let ref_mut: &mut f32 = &mut *p_mut; 22 | } 23 | } -------------------------------------------------------------------------------- /Chapter 9/Codes/Unsafe/Unsafe.rsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | default 6 | 1d4ca75a-4149-45e1-ac01-07e8afa74fd7 7 | exe 8 | Unsafe 9 | Unsafe 10 | Unsafe 11 | 12 | 13 | false 14 | true 15 | 0 16 | default 17 | 18 | 19 | false 20 | false 21 | 2 22 | default 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter 9/Codes/Unsafe/src/main.rs: -------------------------------------------------------------------------------- 1 | use std::mem; 2 | 3 | fn main() { 4 | let v: &[u8] = unsafe { 5 | mem::transmute("Gandalf") 6 | }; 7 | println!("{:?}", v); 8 | } 9 | // [71, 97, 110, 100, 97, 108, 102] -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Chris Ohk 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | --------------------------------------------------------------------------------