18 changed files with 373 additions and 4 deletions
-
2.gitignore
-
6branches/Cargo.lock
-
9branches/Cargo.toml
-
31branches/src/main.rs
-
6functions/Cargo.lock
-
9functions/Cargo.toml
-
12functions/src/main.rs
-
2guessing_game/.gitignore
-
2hello/.gitignore
-
6loops/Cargo.lock
-
9loops/Cargo.toml
-
64loops/src/main.rs
-
6ownership/Cargo.lock
-
9ownership/Cargo.toml
-
183ownership/src/main.rs
-
6variables/Cargo.lock
-
9variables/Cargo.toml
-
6variables/src/main.rs
@ -1 +1,3 @@ |
|||||
|
**/target |
||||
|
**/*.rs.bk |
||||
**/.cargo/* |
**/.cargo/* |
||||
@ -0,0 +1,6 @@ |
|||||
|
# This file is automatically @generated by Cargo. |
||||
|
# It is not intended for manual editing. |
||||
|
[[package]] |
||||
|
name = "branches" |
||||
|
version = "0.1.0" |
||||
|
|
||||
@ -0,0 +1,9 @@ |
|||||
|
[package] |
||||
|
name = "branches" |
||||
|
version = "0.1.0" |
||||
|
authors = ["Georg Hopp <georg@steffers.org>"] |
||||
|
edition = "2018" |
||||
|
|
||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html |
||||
|
|
||||
|
[dependencies] |
||||
@ -0,0 +1,31 @@ |
|||||
|
//
|
||||
|
// Control Flow Examples
|
||||
|
//
|
||||
|
// Georg Hopp <georg@steffers.org>
|
||||
|
//
|
||||
|
// Copyright © 2019 Georg Hopp
|
||||
|
//
|
||||
|
// This program is free software: you can redistribute it and/or modify
|
||||
|
// it under the terms of the GNU General Public License as published by
|
||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||
|
// (at your option) any later version.
|
||||
|
//
|
||||
|
// This program is distributed in the hope that it will be useful,
|
||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
|
// GNU General Public License for more details.
|
||||
|
//
|
||||
|
// You should have received a copy of the GNU General Public License
|
||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
//
|
||||
|
|
||||
|
fn main() {
|
||||
|
let condition = true;
|
||||
|
let number = if condition {
|
||||
|
5
|
||||
|
} else {
|
||||
|
6
|
||||
|
};
|
||||
|
|
||||
|
println!("The value of number is: {}", number);
|
||||
|
}
|
||||
@ -0,0 +1,6 @@ |
|||||
|
# This file is automatically @generated by Cargo. |
||||
|
# It is not intended for manual editing. |
||||
|
[[package]] |
||||
|
name = "functions" |
||||
|
version = "0.1.0" |
||||
|
|
||||
@ -0,0 +1,9 @@ |
|||||
|
[package] |
||||
|
name = "functions" |
||||
|
version = "0.1.0" |
||||
|
authors = ["Georg Hopp <georg@steffers.org>"] |
||||
|
edition = "2018" |
||||
|
|
||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html |
||||
|
|
||||
|
[dependencies] |
||||
@ -0,0 +1,12 @@ |
|||||
|
fn main() {
|
||||
|
another_function(5, add_five(6));
|
||||
|
}
|
||||
|
|
||||
|
fn another_function(x: i32, y: i32) {
|
||||
|
println!("The value of x id: {}", x);
|
||||
|
println!("The value of y id: {}", y);
|
||||
|
}
|
||||
|
|
||||
|
fn add_five(x: i32) -> i32 {
|
||||
|
x + 5
|
||||
|
}
|
||||
@ -1,2 +0,0 @@ |
|||||
/target |
|
||||
**/*.rs.bk |
|
||||
@ -1,2 +0,0 @@ |
|||||
/target |
|
||||
**/*.rs.bk |
|
||||
@ -0,0 +1,6 @@ |
|||||
|
# This file is automatically @generated by Cargo. |
||||
|
# It is not intended for manual editing. |
||||
|
[[package]] |
||||
|
name = "loops" |
||||
|
version = "0.1.0" |
||||
|
|
||||
@ -0,0 +1,9 @@ |
|||||
|
[package] |
||||
|
name = "loops" |
||||
|
version = "0.1.0" |
||||
|
authors = ["Georg Hopp <georg@steffers.org>"] |
||||
|
edition = "2018" |
||||
|
|
||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html |
||||
|
|
||||
|
[dependencies] |
||||
@ -0,0 +1,64 @@ |
|||||
|
//
|
||||
|
// Loops examples.
|
||||
|
//
|
||||
|
// Georg Hopp <georg@steffers.org>
|
||||
|
//
|
||||
|
// Copyright © 2019 Georg Hopp
|
||||
|
//
|
||||
|
// This program is free software: you can redistribute it and/or modify
|
||||
|
// it under the terms of the GNU General Public License as published by
|
||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||
|
// (at your option) any later version.
|
||||
|
//
|
||||
|
// This program is distributed in the hope that it will be useful,
|
||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
|
// GNU General Public License for more details.
|
||||
|
//
|
||||
|
// You should have received a copy of the GNU General Public License
|
||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
//
|
||||
|
|
||||
|
fn main() {
|
||||
|
// It seams that to use loops this way you absolutely need a mutable.
|
||||
|
// If I build it with a normal type and try to shadow it within the loop
|
||||
|
// the outer variable is always used as input for the shadow, thus it is
|
||||
|
// always the same.... that really sucks.
|
||||
|
let mut counter = 0;
|
||||
|
|
||||
|
let result = loop {
|
||||
|
counter = counter + 1;
|
||||
|
if counter == 10 {
|
||||
|
break counter * 2;
|
||||
|
}
|
||||
|
};
|
||||
|
|
||||
|
println!("The result is {}", result);
|
||||
|
|
||||
|
// The same is true with «while» ... which again sucks.
|
||||
|
let mut number = 3;
|
||||
|
|
||||
|
while number != 0 {
|
||||
|
println!("{}!", number);
|
||||
|
number = number - 1;
|
||||
|
}
|
||||
|
|
||||
|
println!("LIFTOFF!!!");
|
||||
|
|
||||
|
// apart from beeing frustrated about the above facts... lets continue.
|
||||
|
let a = [10, 20, 30, 40, 50];
|
||||
|
let mut index = 0;
|
||||
|
|
||||
|
while index < 5 {
|
||||
|
println!("the value is: {}", a[index]);
|
||||
|
index = index + 1;
|
||||
|
}
|
||||
|
|
||||
|
for element in a.iter() {
|
||||
|
println!("the value is still: {}", element);
|
||||
|
}
|
||||
|
|
||||
|
for number in (1..4).rev() {
|
||||
|
println!("for {}!", number);
|
||||
|
}
|
||||
|
}
|
||||
@ -0,0 +1,6 @@ |
|||||
|
# This file is automatically @generated by Cargo. |
||||
|
# It is not intended for manual editing. |
||||
|
[[package]] |
||||
|
name = "ownership" |
||||
|
version = "0.1.0" |
||||
|
|
||||
@ -0,0 +1,9 @@ |
|||||
|
[package] |
||||
|
name = "ownership" |
||||
|
version = "0.1.0" |
||||
|
authors = ["Georg Hopp <georg@steffers.org>"] |
||||
|
edition = "2018" |
||||
|
|
||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html |
||||
|
|
||||
|
[dependencies] |
||||
@ -0,0 +1,183 @@ |
|||||
|
//
|
||||
|
// Examples related to ownership, also introducing String.
|
||||
|
//
|
||||
|
// Georg Hopp <georg@steffers.org>
|
||||
|
//
|
||||
|
// Copyright © 2019 Georg Hopp
|
||||
|
//
|
||||
|
// This program is free software: you can redistribute it and/or modify
|
||||
|
// it under the terms of the GNU General Public License as published by
|
||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||
|
// (at your option) any later version.
|
||||
|
//
|
||||
|
// This program is distributed in the hope that it will be useful,
|
||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
|
// GNU General Public License for more details.
|
||||
|
//
|
||||
|
// You should have received a copy of the GNU General Public License
|
||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
//
|
||||
|
|
||||
|
fn main() {
|
||||
|
concat();
|
||||
|
move_variable();
|
||||
|
clone_variable();
|
||||
|
|
||||
|
let s = String::from("hello"); // s comes into scope
|
||||
|
|
||||
|
take_ownership(s); // s's value moves into the function
|
||||
|
// … and so is no longer valid here.
|
||||
|
let x = 5; // x comes into scope
|
||||
|
|
||||
|
makes_copy(x); // the scalar value has the Copy trait and
|
||||
|
// lives on the stack and thus is still
|
||||
|
// valid here.
|
||||
|
|
||||
|
let _s1 = gives_ownership(); // move the return value into _s1
|
||||
|
let s2 = String::from("hello"); // s2 comes into scope
|
||||
|
let _s3 = takes_and_gives(s2); // s2 is moved into function, which in
|
||||
|
// turn moves the return value into _s3.
|
||||
|
|
||||
|
let s1 = String::from("hello"); // s1 comes into scope.
|
||||
|
let len = calculate_length(&s1); // A reference to s1 is given to a
|
||||
|
// calculate_length which effectively is
|
||||
|
// not s1 itself but another pointer to
|
||||
|
// s1… which is the reason that we still
|
||||
|
// can use it below.
|
||||
|
let _another_s = &s1; // again only a reference which does not
|
||||
|
// take ownership, thus s1 can still be
|
||||
|
// used below.
|
||||
|
println!("The length of '{}' is {}.", s1, len);
|
||||
|
|
||||
|
// Passing values as reference to a function is called borrowing. A
|
||||
|
// borrowed value can't be changed.
|
||||
|
change(&s1);
|
||||
|
|
||||
|
// but we can force this… which is probably not the best of ideas most
|
||||
|
// of the time…
|
||||
|
let mut s_mut = String::from("hello");
|
||||
|
change_mutable(&mut s_mut);
|
||||
|
|
||||
|
// but you can have only one mutable reference of a value in a single
|
||||
|
// scope. The following would fail with:
|
||||
|
// cannot borrow `s_mut` as mutable more than once at a time second
|
||||
|
// mutable borrow occurs here
|
||||
|
// let r1 = &mut s_mut;
|
||||
|
// let r2 = &mut s_mut;
|
||||
|
// println!("{}, {}", r1, r2);
|
||||
|
|
||||
|
// We also can't have an immutable reference while we have a mutable one.
|
||||
|
// Look on Page 98 for an explanation.
|
||||
|
|
||||
|
// The scope of references is not the whole block they are introduced in
|
||||
|
// but goes only until their last usage. Thus if you first have an
|
||||
|
// immutable reference but never use it after a mutable reference is
|
||||
|
// declared, that would be ok… At all this is kind of confusing and very
|
||||
|
// Mozzilaish. :D
|
||||
|
|
||||
|
// Now we demonstrate string slices…
|
||||
|
let s4 = String::from("hello world");
|
||||
|
let s_slice = first_word(&s4);
|
||||
|
|
||||
|
// working with an mutable reference like with s4.clear() will not
|
||||
|
// compile at this point because we already have and use later on an
|
||||
|
// immutable reference.
|
||||
|
|
||||
|
println!("The slice was: {}", s_slice);
|
||||
|
|
||||
|
// not that string literals are slices. They are immutable references of
|
||||
|
// the programs TEXT segment. Thats the reason why they are immutable.
|
||||
|
|
||||
|
// Thus try generic_first_word…
|
||||
|
println!("First word on literal: {}", generic_first_word("hello world"));
|
||||
|
println!("First word on String: {}", generic_first_word(&s4[..]));
|
||||
|
} // x and s go out of scope but nothing happens for s because this function
|
||||
|
// has no longer the ownership of s.
|
||||
|
// s3 goes out of scope and is dropped. s2 was moved and s1 is dropped.
|
||||
|
|
||||
|
fn concat() {
|
||||
|
let mut s = String::from("hello");
|
||||
|
s.push_str(", world!");
|
||||
|
println!("{}", s);
|
||||
|
}
|
||||
|
|
||||
|
fn move_variable() {
|
||||
|
let s1 = String::from("hello");
|
||||
|
let s2 = s1; // does not copy data but only the String structure.
|
||||
|
// when using s1 below we get an error that a moved value was borrowed.
|
||||
|
println!("{}, world!", s2);
|
||||
|
}
|
||||
|
|
||||
|
fn clone_variable() {
|
||||
|
let s1 = String::from("hello");
|
||||
|
let s2 = s1.clone();
|
||||
|
// this time both are valid.
|
||||
|
println!("s1 = {}, s2 = {}", s1, s2)
|
||||
|
}
|
||||
|
|
||||
|
fn take_ownership(some_string: String) { // some_string comes into scope
|
||||
|
println!("{}", some_string);
|
||||
|
} // some_string goes out of scope and «drop» is called, thus memory freed.
|
||||
|
|
||||
|
fn makes_copy(some_integer: i32) { // some integer comes into scope
|
||||
|
println!("{}", some_integer);
|
||||
|
} // Here, some_integer goes out of scope but because it was a copy and on the
|
||||
|
// stack nothing special happens… beside that stack space is freed.
|
||||
|
|
||||
|
fn gives_ownership() -> String { // this will move the return value into the
|
||||
|
// calling function.
|
||||
|
let some_string = String::from("hello"); // some_string comes into scope
|
||||
|
some_string
|
||||
|
}
|
||||
|
|
||||
|
fn takes_and_gives(a_string: String) -> String { // a_string comes into scope
|
||||
|
a_string // and is returned and moved
|
||||
|
// to the calling function.
|
||||
|
} // a_string goes out of scope but nothing happens as it is moved.
|
||||
|
|
||||
|
fn calculate_length(s: &String) -> usize { // s comes into scope. It is a
|
||||
|
// reference. References do not
|
||||
|
// take ownership of the underlying
|
||||
|
// value which is the String in
|
||||
|
// main.
|
||||
|
s.len()
|
||||
|
} // Here s goes out of scope but because it has no ownership of the String
|
||||
|
// nothing happens.
|
||||
|
|
||||
|
fn change(_some_string: &String) {
|
||||
|
// the following would give this error:
|
||||
|
// `_some_string` is a `&` reference, so the data it refers to cannot be
|
||||
|
// borrowed as mutable
|
||||
|
// _some_string.push_str(", world!");
|
||||
|
}
|
||||
|
|
||||
|
fn change_mutable(some_string: &mut String) {
|
||||
|
some_string.push_str(", world");
|
||||
|
}
|
||||
|
|
||||
|
fn first_word(s: &String) -> &str {
|
||||
|
let bytes = s.as_bytes();
|
||||
|
|
||||
|
for (i, &item) in bytes.iter().enumerate() {
|
||||
|
if item == b' ' {
|
||||
|
return &s[..i];
|
||||
|
}
|
||||
|
}
|
||||
|
|
||||
|
&s[..]
|
||||
|
}
|
||||
|
|
||||
|
// To make first_word work on either string literals (which are in fact string
|
||||
|
// slices, s.o.) one would write first_word like this…
|
||||
|
fn generic_first_word(s: &str) -> &str {
|
||||
|
let bytes = s.as_bytes();
|
||||
|
|
||||
|
for (i, &item) in bytes.iter().enumerate() {
|
||||
|
if item == b' ' {
|
||||
|
return &s[..i];
|
||||
|
}
|
||||
|
}
|
||||
|
|
||||
|
&s[..]
|
||||
|
}
|
||||
@ -0,0 +1,6 @@ |
|||||
|
# This file is automatically @generated by Cargo. |
||||
|
# It is not intended for manual editing. |
||||
|
[[package]] |
||||
|
name = "variables" |
||||
|
version = "0.1.0" |
||||
|
|
||||
@ -0,0 +1,9 @@ |
|||||
|
[package] |
||||
|
name = "variables" |
||||
|
version = "0.1.0" |
||||
|
authors = ["Georg Hopp <georg@steffers.org>"] |
||||
|
edition = "2018" |
||||
|
|
||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html |
||||
|
|
||||
|
[dependencies] |
||||
@ -0,0 +1,6 @@ |
|||||
|
fn main() {
|
||||
|
let mut x = 5;
|
||||
|
println!("The value of x is: {}", x);
|
||||
|
x = 6;
|
||||
|
println!("The value of x is: {}", x);
|
||||
|
}
|
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue