Showing
18 changed files
with
373 additions
and
4 deletions
branches/Cargo.lock
0 → 100644
branches/Cargo.toml
0 → 100644
branches/src/main.rs
0 → 100644
| 1 | +// | |
| 2 | +// Control Flow Examples | |
| 3 | +// | |
| 4 | +// Georg Hopp <georg@steffers.org> | |
| 5 | +// | |
| 6 | +// Copyright © 2019 Georg Hopp | |
| 7 | +// | |
| 8 | +// This program is free software: you can redistribute it and/or modify | |
| 9 | +// it under the terms of the GNU General Public License as published by | |
| 10 | +// the Free Software Foundation, either version 3 of the License, or | |
| 11 | +// (at your option) any later version. | |
| 12 | +// | |
| 13 | +// This program is distributed in the hope that it will be useful, | |
| 14 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 15 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 16 | +// GNU General Public License for more details. | |
| 17 | +// | |
| 18 | +// You should have received a copy of the GNU General Public License | |
| 19 | +// along with this program. If not, see <http://www.gnu.org/licenses/>. | |
| 20 | +// | |
| 21 | + | |
| 22 | +fn main() { | |
| 23 | + let condition = true; | |
| 24 | + let number = if condition { | |
| 25 | + 5 | |
| 26 | + } else { | |
| 27 | + 6 | |
| 28 | + }; | |
| 29 | + | |
| 30 | + println!("The value of number is: {}", number); | |
| 31 | +} | ... | ... |
functions/Cargo.lock
0 → 100644
functions/Cargo.toml
0 → 100644
functions/src/main.rs
0 → 100644
guessing_game/.gitignore
deleted
100644 → 0
hello/.gitignore
deleted
100644 → 0
loops/Cargo.lock
0 → 100644
loops/Cargo.toml
0 → 100644
loops/src/main.rs
0 → 100644
| 1 | +// | |
| 2 | +// Loops examples. | |
| 3 | +// | |
| 4 | +// Georg Hopp <georg@steffers.org> | |
| 5 | +// | |
| 6 | +// Copyright © 2019 Georg Hopp | |
| 7 | +// | |
| 8 | +// This program is free software: you can redistribute it and/or modify | |
| 9 | +// it under the terms of the GNU General Public License as published by | |
| 10 | +// the Free Software Foundation, either version 3 of the License, or | |
| 11 | +// (at your option) any later version. | |
| 12 | +// | |
| 13 | +// This program is distributed in the hope that it will be useful, | |
| 14 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 15 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 16 | +// GNU General Public License for more details. | |
| 17 | +// | |
| 18 | +// You should have received a copy of the GNU General Public License | |
| 19 | +// along with this program. If not, see <http://www.gnu.org/licenses/>. | |
| 20 | +// | |
| 21 | + | |
| 22 | +fn main() { | |
| 23 | + // It seams that to use loops this way you absolutely need a mutable. | |
| 24 | + // If I build it with a normal type and try to shadow it within the loop | |
| 25 | + // the outer variable is always used as input for the shadow, thus it is | |
| 26 | + // always the same.... that really sucks. | |
| 27 | + let mut counter = 0; | |
| 28 | + | |
| 29 | + let result = loop { | |
| 30 | + counter = counter + 1; | |
| 31 | + if counter == 10 { | |
| 32 | + break counter * 2; | |
| 33 | + } | |
| 34 | + }; | |
| 35 | + | |
| 36 | + println!("The result is {}", result); | |
| 37 | + | |
| 38 | + // The same is true with «while» ... which again sucks. | |
| 39 | + let mut number = 3; | |
| 40 | + | |
| 41 | + while number != 0 { | |
| 42 | + println!("{}!", number); | |
| 43 | + number = number - 1; | |
| 44 | + } | |
| 45 | + | |
| 46 | + println!("LIFTOFF!!!"); | |
| 47 | + | |
| 48 | + // apart from beeing frustrated about the above facts... lets continue. | |
| 49 | + let a = [10, 20, 30, 40, 50]; | |
| 50 | + let mut index = 0; | |
| 51 | + | |
| 52 | + while index < 5 { | |
| 53 | + println!("the value is: {}", a[index]); | |
| 54 | + index = index + 1; | |
| 55 | + } | |
| 56 | + | |
| 57 | + for element in a.iter() { | |
| 58 | + println!("the value is still: {}", element); | |
| 59 | + } | |
| 60 | + | |
| 61 | + for number in (1..4).rev() { | |
| 62 | + println!("for {}!", number); | |
| 63 | + } | |
| 64 | +} | ... | ... |
ownership/Cargo.lock
0 → 100644
ownership/Cargo.toml
0 → 100644
ownership/src/main.rs
0 → 100644
| 1 | +// | |
| 2 | +// Examples related to ownership, also introducing String. | |
| 3 | +// | |
| 4 | +// Georg Hopp <georg@steffers.org> | |
| 5 | +// | |
| 6 | +// Copyright © 2019 Georg Hopp | |
| 7 | +// | |
| 8 | +// This program is free software: you can redistribute it and/or modify | |
| 9 | +// it under the terms of the GNU General Public License as published by | |
| 10 | +// the Free Software Foundation, either version 3 of the License, or | |
| 11 | +// (at your option) any later version. | |
| 12 | +// | |
| 13 | +// This program is distributed in the hope that it will be useful, | |
| 14 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 15 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 16 | +// GNU General Public License for more details. | |
| 17 | +// | |
| 18 | +// You should have received a copy of the GNU General Public License | |
| 19 | +// along with this program. If not, see <http://www.gnu.org/licenses/>. | |
| 20 | +// | |
| 21 | + | |
| 22 | +fn main() { | |
| 23 | + concat(); | |
| 24 | + move_variable(); | |
| 25 | + clone_variable(); | |
| 26 | + | |
| 27 | + let s = String::from("hello"); // s comes into scope | |
| 28 | + | |
| 29 | + take_ownership(s); // s's value moves into the function | |
| 30 | + // … and so is no longer valid here. | |
| 31 | + let x = 5; // x comes into scope | |
| 32 | + | |
| 33 | + makes_copy(x); // the scalar value has the Copy trait and | |
| 34 | + // lives on the stack and thus is still | |
| 35 | + // valid here. | |
| 36 | + | |
| 37 | + let _s1 = gives_ownership(); // move the return value into _s1 | |
| 38 | + let s2 = String::from("hello"); // s2 comes into scope | |
| 39 | + let _s3 = takes_and_gives(s2); // s2 is moved into function, which in | |
| 40 | + // turn moves the return value into _s3. | |
| 41 | + | |
| 42 | + let s1 = String::from("hello"); // s1 comes into scope. | |
| 43 | + let len = calculate_length(&s1); // A reference to s1 is given to a | |
| 44 | + // calculate_length which effectively is | |
| 45 | + // not s1 itself but another pointer to | |
| 46 | + // s1… which is the reason that we still | |
| 47 | + // can use it below. | |
| 48 | + let _another_s = &s1; // again only a reference which does not | |
| 49 | + // take ownership, thus s1 can still be | |
| 50 | + // used below. | |
| 51 | + println!("The length of '{}' is {}.", s1, len); | |
| 52 | + | |
| 53 | + // Passing values as reference to a function is called borrowing. A | |
| 54 | + // borrowed value can't be changed. | |
| 55 | + change(&s1); | |
| 56 | + | |
| 57 | + // but we can force this… which is probably not the best of ideas most | |
| 58 | + // of the time… | |
| 59 | + let mut s_mut = String::from("hello"); | |
| 60 | + change_mutable(&mut s_mut); | |
| 61 | + | |
| 62 | + // but you can have only one mutable reference of a value in a single | |
| 63 | + // scope. The following would fail with: | |
| 64 | + // cannot borrow `s_mut` as mutable more than once at a time second | |
| 65 | + // mutable borrow occurs here | |
| 66 | + // let r1 = &mut s_mut; | |
| 67 | + // let r2 = &mut s_mut; | |
| 68 | + // println!("{}, {}", r1, r2); | |
| 69 | + | |
| 70 | + // We also can't have an immutable reference while we have a mutable one. | |
| 71 | + // Look on Page 98 for an explanation. | |
| 72 | + | |
| 73 | + // The scope of references is not the whole block they are introduced in | |
| 74 | + // but goes only until their last usage. Thus if you first have an | |
| 75 | + // immutable reference but never use it after a mutable reference is | |
| 76 | + // declared, that would be ok… At all this is kind of confusing and very | |
| 77 | + // Mozzilaish. :D | |
| 78 | + | |
| 79 | + // Now we demonstrate string slices… | |
| 80 | + let s4 = String::from("hello world"); | |
| 81 | + let s_slice = first_word(&s4); | |
| 82 | + | |
| 83 | + // working with an mutable reference like with s4.clear() will not | |
| 84 | + // compile at this point because we already have and use later on an | |
| 85 | + // immutable reference. | |
| 86 | + | |
| 87 | + println!("The slice was: {}", s_slice); | |
| 88 | + | |
| 89 | + // not that string literals are slices. They are immutable references of | |
| 90 | + // the programs TEXT segment. Thats the reason why they are immutable. | |
| 91 | + | |
| 92 | + // Thus try generic_first_word… | |
| 93 | + println!("First word on literal: {}", generic_first_word("hello world")); | |
| 94 | + println!("First word on String: {}", generic_first_word(&s4[..])); | |
| 95 | +} // x and s go out of scope but nothing happens for s because this function | |
| 96 | + // has no longer the ownership of s. | |
| 97 | + // s3 goes out of scope and is dropped. s2 was moved and s1 is dropped. | |
| 98 | + | |
| 99 | +fn concat() { | |
| 100 | + let mut s = String::from("hello"); | |
| 101 | + s.push_str(", world!"); | |
| 102 | + println!("{}", s); | |
| 103 | +} | |
| 104 | + | |
| 105 | +fn move_variable() { | |
| 106 | + let s1 = String::from("hello"); | |
| 107 | + let s2 = s1; // does not copy data but only the String structure. | |
| 108 | + // when using s1 below we get an error that a moved value was borrowed. | |
| 109 | + println!("{}, world!", s2); | |
| 110 | +} | |
| 111 | + | |
| 112 | +fn clone_variable() { | |
| 113 | + let s1 = String::from("hello"); | |
| 114 | + let s2 = s1.clone(); | |
| 115 | + // this time both are valid. | |
| 116 | + println!("s1 = {}, s2 = {}", s1, s2) | |
| 117 | +} | |
| 118 | + | |
| 119 | +fn take_ownership(some_string: String) { // some_string comes into scope | |
| 120 | + println!("{}", some_string); | |
| 121 | +} // some_string goes out of scope and «drop» is called, thus memory freed. | |
| 122 | + | |
| 123 | +fn makes_copy(some_integer: i32) { // some integer comes into scope | |
| 124 | + println!("{}", some_integer); | |
| 125 | +} // Here, some_integer goes out of scope but because it was a copy and on the | |
| 126 | + // stack nothing special happens… beside that stack space is freed. | |
| 127 | + | |
| 128 | +fn gives_ownership() -> String { // this will move the return value into the | |
| 129 | + // calling function. | |
| 130 | + let some_string = String::from("hello"); // some_string comes into scope | |
| 131 | + some_string | |
| 132 | +} | |
| 133 | + | |
| 134 | +fn takes_and_gives(a_string: String) -> String { // a_string comes into scope | |
| 135 | + a_string // and is returned and moved | |
| 136 | + // to the calling function. | |
| 137 | +} // a_string goes out of scope but nothing happens as it is moved. | |
| 138 | + | |
| 139 | +fn calculate_length(s: &String) -> usize { // s comes into scope. It is a | |
| 140 | + // reference. References do not | |
| 141 | + // take ownership of the underlying | |
| 142 | + // value which is the String in | |
| 143 | + // main. | |
| 144 | + s.len() | |
| 145 | +} // Here s goes out of scope but because it has no ownership of the String | |
| 146 | + // nothing happens. | |
| 147 | + | |
| 148 | +fn change(_some_string: &String) { | |
| 149 | + // the following would give this error: | |
| 150 | + // `_some_string` is a `&` reference, so the data it refers to cannot be | |
| 151 | + // borrowed as mutable | |
| 152 | + // _some_string.push_str(", world!"); | |
| 153 | +} | |
| 154 | + | |
| 155 | +fn change_mutable(some_string: &mut String) { | |
| 156 | + some_string.push_str(", world"); | |
| 157 | +} | |
| 158 | + | |
| 159 | +fn first_word(s: &String) -> &str { | |
| 160 | + let bytes = s.as_bytes(); | |
| 161 | + | |
| 162 | + for (i, &item) in bytes.iter().enumerate() { | |
| 163 | + if item == b' ' { | |
| 164 | + return &s[..i]; | |
| 165 | + } | |
| 166 | + } | |
| 167 | + | |
| 168 | + &s[..] | |
| 169 | +} | |
| 170 | + | |
| 171 | +// To make first_word work on either string literals (which are in fact string | |
| 172 | +// slices, s.o.) one would write first_word like this… | |
| 173 | +fn generic_first_word(s: &str) -> &str { | |
| 174 | + let bytes = s.as_bytes(); | |
| 175 | + | |
| 176 | + for (i, &item) in bytes.iter().enumerate() { | |
| 177 | + if item == b' ' { | |
| 178 | + return &s[..i]; | |
| 179 | + } | |
| 180 | + } | |
| 181 | + | |
| 182 | + &s[..] | |
| 183 | +} | ... | ... |
variables/Cargo.lock
0 → 100644
variables/Cargo.toml
0 → 100644
Please
register
or
login
to post a comment