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