├── .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 |
--------------------------------------------------------------------------------