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