├── Chapter 1 ├── code │ ├── welcome.rs │ └── welcomec │ │ ├── .gitignore │ │ ├── Cargo.lock │ │ ├── Cargo.toml │ │ └── src │ │ └── main.rs └── exercises │ ├── name.rs │ └── smallest_program.rs ├── Chapter 10 └── code │ ├── a │ └── b.txt │ ├── filesystem.rs │ ├── hello.txt │ ├── info.txt │ ├── lorem_ipsum.txt │ ├── lorem_ipsum2.txt │ ├── numbers.txt │ ├── paths.rs │ ├── read_file.rs │ ├── read_file_try.rs │ ├── read_files_in_dir.rs │ ├── reading_text_file.rs │ ├── write_file.rs │ └── write_file_try.rs ├── Chapter 2 ├── code │ ├── alias.rs │ ├── bindings.rs │ ├── comments.rs │ ├── constants1.rs │ ├── constants2.rs │ ├── expressions.rs │ ├── mutable_constant.rs │ ├── references.rs │ ├── scope.rs │ ├── test.rs │ ├── type_conversions.rs │ ├── type_errors.rs │ └── types2.rs └── exercises │ ├── change_constant.rs │ ├── compound_let.rs │ └── formatting.rs ├── Chapter 3 ├── code │ ├── attributes_cfg.rs │ ├── attributes_testing.rs │ ├── doc │ │ ├── .lock │ │ ├── FiraSans-Medium.woff │ │ ├── FiraSans-Regular.woff │ │ ├── Heuristica-Italic.woff │ │ ├── SourceCodePro-Regular.woff │ │ ├── SourceCodePro-Semibold.woff │ │ ├── SourceSerifPro-Bold.woff │ │ ├── SourceSerifPro-Regular.woff │ │ ├── exdoc │ │ │ ├── fn.cube.html │ │ │ ├── index.html │ │ │ ├── sidebar-items.js │ │ │ ├── stability.html │ │ │ └── stability.json │ │ ├── jquery.js │ │ ├── main.css │ │ ├── main.js │ │ ├── normalize.css │ │ ├── playpen.js │ │ ├── search-index.js │ │ └── src │ │ │ └── exdoc │ │ │ └── exdoc.rs │ │ │ └── exdoc.rs.html │ ├── exdoc.rs │ ├── fib_procedural.rs │ ├── functions.rs │ ├── ifelse.rs │ ├── iter_step.rs │ ├── loops.rs │ ├── mylib │ │ ├── .gitignore │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── nested_function.rs │ └── random.rs └── exercises │ ├── absolute.rs │ ├── ifreturn.rs │ └── iftest.rs ├── Chapter 4 ├── code │ ├── arrays.rs │ ├── destructure_enum.rs │ ├── destructuring_structs.rs │ ├── enums.rs │ ├── enums2.rs │ ├── input.rs │ ├── match_tuple.rs │ ├── pattern_match.rs │ ├── pattern_match2.rs │ ├── remove_elem_vector.rs │ ├── strings.rs │ ├── structs.rs │ └── tuples.rs └── exercises │ ├── chars_string.rs │ ├── match_type.rs │ ├── matching.rs │ ├── monster.rs │ ├── pattern_match.rs │ └── tuples_ex.rs ├── Chapter 5 ├── code │ ├── adapters_consumers.rs │ ├── dispatch.rs │ ├── errors.rs │ ├── generics.rs │ ├── higher_functions.rs │ ├── impl_add.rs │ ├── input_number.rs │ ├── input_number2.rs │ ├── iterators.rs │ ├── method_enum.rs │ ├── methods.rs │ ├── sqrt_match.rs │ ├── super_traits.rs │ ├── trait_constraints │ │ ├── Cargo.lock │ │ ├── Cargo.toml │ │ ├── src │ │ │ └── trait_constraints.rs │ │ └── target │ │ │ └── debug │ │ │ ├── .fingerprint │ │ │ ├── libc-674726c388d62fa2 │ │ │ │ ├── dep-lib-libc │ │ │ │ └── lib-libc │ │ │ ├── num-b6664aad0573bf89 │ │ │ │ ├── dep-lib-num │ │ │ │ └── lib-num │ │ │ ├── rand-b924d9fc5b3eb5b8 │ │ │ │ ├── dep-lib-rand │ │ │ │ └── lib-rand │ │ │ ├── rustc-serialize-9ef26f158d5284e0 │ │ │ │ ├── dep-lib-rustc-serialize │ │ │ │ └── lib-rustc-serialize │ │ │ └── trait_constraints-43ecad8ba4135d3d │ │ │ │ ├── bin-trait_constraints │ │ │ │ └── dep-bin-trait_constraints │ │ │ ├── deps │ │ │ ├── liblibc-674726c388d62fa2.rlib │ │ │ ├── libnum-b6664aad0573bf89.rlib │ │ │ ├── librand-b924d9fc5b3eb5b8.rlib │ │ │ └── librustc_serialize-9ef26f158d5284e0.rlib │ │ │ └── trait_constraints.exe │ ├── traits.rs │ ├── try_input_number.rs │ └── write.rs └── exercises │ ├── complex.rs │ ├── draw_trait.rs │ ├── fold.rs │ └── range_next.rs ├── Chapter 6 ├── code │ ├── boxes1.rs │ ├── boxes2.rs │ ├── boxes_experimental.rs │ ├── clone.rs │ ├── drop.rs │ ├── errors.rs │ ├── lifetimes.rs │ ├── linked_list.rs │ ├── moving_closure.rs │ ├── ownership1.rs │ ├── ownership2.rs │ ├── ref.rs │ ├── ref_count_notgood.rs │ ├── refcount.rs │ └── references.rs └── exercises │ ├── dangling_pointer.rs │ ├── grow_a_tentacle.rs │ ├── increment_vector.rs │ ├── ownership3.rs │ └── pointer_mutability.rs ├── Chapter 7 ├── code │ ├── builtin_macros.rs │ ├── cube │ │ ├── .gitignore │ │ ├── Cargo.toml │ │ ├── src │ │ │ ├── lib.rs │ │ │ └── test.rs │ │ └── tests │ │ │ └── lib.rs │ ├── import_modules.rs │ ├── libmycrate.rlib │ ├── libstructs.rlib │ ├── macro_debug.rs │ ├── macros.rs │ ├── mod_private.rs │ ├── modul1 │ │ └── mod.rs │ ├── modul2.rs │ ├── modules.rs │ ├── monsters │ │ ├── .gitignore │ │ ├── Cargo.toml │ │ └── src │ │ │ ├── lib.rs │ │ │ └── main.rs │ ├── random │ │ ├── .gitignore │ │ ├── Cargo.lock │ │ ├── Cargo.toml │ │ └── src │ │ │ └── main.rs │ └── structs.rs └── exercises │ ├── macro_ex.rs │ └── priv_struct.rs ├── Chapter 8 ├── code │ ├── change_vec.rs │ ├── channel_box.rs │ ├── channels.rs │ ├── channels2.rs │ ├── channels_struct.rs │ ├── make_channel.rs │ ├── many_threads.rs │ ├── many_threads │ │ ├── .gitignore │ │ ├── Cargo.lock │ │ ├── Cargo.toml │ │ └── src │ │ │ └── main.rs │ ├── moving_closure.rs │ ├── not_shared.rs │ ├── panic_thread.rs │ ├── sync_channel.rs │ ├── thread_safe.rs │ └── thread_spawn.rs └── exercises │ ├── exc_thread_safe.rs │ └── shared_channel.rs ├── Chapter 9 └── code │ ├── arguments.rs │ ├── asm.rs │ ├── calling_clibrary.rs │ ├── calling_libc.rs │ ├── parsing_argument.rs │ ├── pointer_offset.rs │ ├── raw_pointers.rs │ ├── size_of_val.rs │ ├── swap.rs │ └── unsafe.rs └── README.md /Chapter 1/code/welcome.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | println!("Welcome to the Game!"); 3 | } -------------------------------------------------------------------------------- /Chapter 1/code/welcomec/.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | -------------------------------------------------------------------------------- /Chapter 1/code/welcomec/Cargo.lock: -------------------------------------------------------------------------------- 1 | [root] 2 | name = "welcomec" 3 | version = "0.0.1" 4 | 5 | -------------------------------------------------------------------------------- /Chapter 1/code/welcomec/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | 3 | name = "welcomec" 4 | version = "0.0.1" 5 | authors = ["Ivo Balbaert "] 6 | -------------------------------------------------------------------------------- /Chapter 1/code/welcomec/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | println!("Hello, world!"); 3 | } 4 | -------------------------------------------------------------------------------- /Chapter 1/exercises/name.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | println!("My name is Ivo Balbaert"); 3 | } -------------------------------------------------------------------------------- /Chapter 1/exercises/smallest_program.rs: -------------------------------------------------------------------------------- 1 | fn main() {} -------------------------------------------------------------------------------- /Chapter 10/code/a/b.txt: -------------------------------------------------------------------------------- 1 | hello -------------------------------------------------------------------------------- /Chapter 10/code/filesystem.rs: -------------------------------------------------------------------------------- 1 | // #![feature(fs_walk)] 2 | 3 | use std::fs; 4 | use std::fs::{File, OpenOptions}; 5 | use std::io; 6 | use std::io::prelude::*; 7 | // use std::os::unix 8 | use std::path::Path; 9 | 10 | // A simple implementation of `% cat path` 11 | fn cat(path: &Path) -> io::Result { 12 | let mut f = try!(File::open(path)); 13 | let mut s = String::new(); 14 | match f.read_to_string(&mut s) { 15 | Ok(_) => Ok(s), 16 | Err(e) => Err(e), 17 | } 18 | } 19 | 20 | // A simple implementation of `% echo s > path` 21 | fn echo(s: &str, path: &Path) -> io::Result<()> { 22 | let mut f = try!(File::create(path)); 23 | 24 | f.write_all(s.as_bytes()) 25 | } 26 | 27 | // A simple implementation of `% touch path` (ignores existing files) 28 | fn touch(path: &Path) -> io::Result<()> { 29 | match OpenOptions::new().create(true).open(path) { 30 | Ok(_) => Ok(()), 31 | Err(e) => Err(e), 32 | } 33 | } 34 | 35 | fn main() { 36 | println!("`mkdir a`"); 37 | // Create a directory, returns `io::Result<()>` 38 | match fs::create_dir("a") { 39 | Err(why) => println!("! {:?}", why.kind()), 40 | Ok(_) => {}, 41 | } 42 | 43 | println!("`echo hello > a/b.txt`"); 44 | // The previous match can be simplified using the `unwrap_or_else` method 45 | echo("hello", &Path::new("a/b.txt")).unwrap_or_else(|why| { 46 | println!("! {:?}", why.kind()); 47 | }); 48 | 49 | println!("`mkdir -p a/c/d`"); 50 | // Recursively create a directory, returns `io::Result<()>` 51 | fs::create_dir_all("a/c/d").unwrap_or_else(|why| { 52 | println!("! {:?}", why.kind()); 53 | }); 54 | 55 | println!("`touch a/c/e.txt`"); 56 | touch(&Path::new("a/c/e.txt")).unwrap_or_else(|why| { 57 | println!("! {:?}", why.kind()); 58 | }); 59 | 60 | println!("`ln -s ../b.txt a/c/b.txt`"); 61 | // Create a symbolic link, returns `io::Result<()>` 62 | // if cfg!(target_family = "unix") { 63 | // unix::fs::symlink("../b.txt", "a/c/b.txt").unwrap_or_else(|why| { 64 | // println!("! {:?}", why.kind()); 65 | // }); 66 | // } 67 | 68 | println!("`cat a/c/b.txt`"); 69 | match cat(&Path::new("a/c/b.txt")) { 70 | Err(why) => println!("! {:?}", why.kind()), 71 | Ok(s) => println!("> {}", s), 72 | } 73 | 74 | println!("`ls a`"); 75 | // Read the contents of a directory: 76 | match fs::read_dir("a") { 77 | Err(why) => println!("! {:?}", why.kind()), 78 | Ok(paths) => for path in paths { 79 | println!("> {:?}", path.unwrap().path()); 80 | }, 81 | } 82 | 83 | // println!("`walk a`"); 84 | // // Recursively walk over the contents of a directory, returns 85 | // // `Directories`, which implements the `Iterator trait 86 | // match fs::walk_dir("a") { 87 | // Err(why) => println!("! {:?}", why.kind()), 88 | // Ok(paths) => for path in paths { 89 | // println!("> {:?}", path.unwrap().path()); 90 | // }, 91 | // } 92 | 93 | println!("`rm a/c/e.txt`"); 94 | // Remove a file, returns `io::Result<()>` 95 | fs::remove_file("a/c/e.txt").unwrap_or_else(|why| { 96 | println!("! {:?}", why.kind()); 97 | }); 98 | 99 | println!("`rmdir a/c/d`"); 100 | // Remove an empty directory, returns `io::Result<()>` 101 | fs::remove_dir("a/c/d").unwrap_or_else(|why| { 102 | println!("! {:?}", why.kind()); 103 | }); 104 | } 105 | // `mkdir a` 106 | // `echo hello > a/b.txt` 107 | // `mkdir -p a/c/d` 108 | // `touch a/c/e.txt` 109 | // `ln -s ../b.txt a/c/b.txt` 110 | // `cat a/c/b.txt` 111 | // ! NotFound 112 | // `ls a` 113 | // > "a\b.txt" 114 | // > "a\c" 115 | // `rm a/c/e.txt` 116 | // `rmdir a/c/d` -------------------------------------------------------------------------------- /Chapter 10/code/hello.txt: -------------------------------------------------------------------------------- 1 | "Hello Rust World!" 2 | -------------------------------------------------------------------------------- /Chapter 10/code/info.txt: -------------------------------------------------------------------------------- 1 | Barak 2 | Vladimir -------------------------------------------------------------------------------- /Chapter 10/code/lorem_ipsum.txt: -------------------------------------------------------------------------------- 1 | Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod 2 | tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, 3 | quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo 4 | consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse 5 | cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non 6 | proident, sunt in culpa qui officia deserunt mollit anim id est laborum. 7 | -------------------------------------------------------------------------------- /Chapter 10/code/lorem_ipsum2.txt: -------------------------------------------------------------------------------- 1 | Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod 2 | tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, 3 | quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo 4 | consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse 5 | cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non 6 | proident, sunt in culpa qui officia deserunt mollit anim id est laborum. 7 | -------------------------------------------------------------------------------- /Chapter 10/code/numbers.txt: -------------------------------------------------------------------------------- 1 | 120 345.56 2 | 125 341.56 -------------------------------------------------------------------------------- /Chapter 10/code/paths.rs: -------------------------------------------------------------------------------- 1 | // #![feature(path_ext)] 2 | 3 | use std::path::Path; 4 | // use std::fs::PathExt; 5 | 6 | fn main() { 7 | let path = Path::new("hello2.txt"); 8 | let display = path.display(); 9 | 10 | // test whether path exists: use with feature gat path_ext 11 | // if path.exists() { 12 | // println!("{} exists", display); 13 | // } 14 | // else { 15 | // panic!("This path or file does not exist!"); 16 | // } 17 | 18 | let file = path.file_name().unwrap(); 19 | let extension = path.extension().unwrap(); 20 | let parent_dir = path.parent().unwrap(); 21 | println!("This is file {:?} with extension {:?} in folder {:?}", file, extension, parent_dir); 22 | 23 | // Check if the path is a file 24 | // if path.is_file() { println!("{} is a file", display); } 25 | // Check if the path is a directory 26 | // if path.is_dir() { println!("{} is a directory", display); } 27 | 28 | // `join` merges a path with a byte container using the OS specific 29 | // separator, and returns the new path 30 | let new_path = path.join("abc").join("def"); 31 | 32 | // Convert the path into a string slice 33 | match new_path.to_str() { 34 | None => panic!("new path is not a valid UTF-8 sequence"), 35 | Some(s) => println!("new path is {}", s), 36 | } 37 | } 38 | // This is file "hello2.txt" with extension "txt" in folder "" 39 | // new path is hello2.txt\abc\def 40 | -------------------------------------------------------------------------------- /Chapter 10/code/read_file.rs: -------------------------------------------------------------------------------- 1 | use std::path::Path; 2 | use std::fs::File; 3 | use std::io::prelude::*; 4 | use std::error::Error; 5 | 6 | fn main() { 7 | let path = Path::new("hello.txt"); 8 | let display = path.display(); 9 | 10 | // opening a file: 11 | let mut file = match File::open(&path) { 12 | Ok(file) => file, 13 | Err(why) => panic!("couldn't open {}: {}", display, Error::description(&why)) 14 | }; 15 | 16 | // reading a file in one chunk: 17 | let mut content = String::new(); 18 | match file.read_to_string(&mut content) { 19 | Err(why) => panic!("couldn't read {}: {}", display, Error::description(&why)), 20 | Ok(_) => print!("{} contains:\n{}", display, content), 21 | } 22 | } 23 | // hello.txt contains: 24 | // "Hello Rust World!" -------------------------------------------------------------------------------- /Chapter 10/code/read_file_try.rs: -------------------------------------------------------------------------------- 1 | use std::path::Path; 2 | use std::fs::File; 3 | use std::io::prelude::*; 4 | use std::error::Error; 5 | use std::io; 6 | 7 | fn main() { 8 | let path = Path::new("hello.txt"); 9 | let display = path.display(); 10 | 11 | let content = match read_file(path) { 12 | Err(why) => panic!("error reading {}: {}", display, Error::description(&why)), 13 | Ok(content) => content 14 | }; 15 | 16 | println!("{}", content); 17 | } 18 | 19 | fn read_file(path: &Path) -> Result { 20 | let mut file = try!(File::open(path)); 21 | let mut buf = String::new(); 22 | try!(file.read_to_string(&mut buf)); 23 | Ok(buf) 24 | } 25 | // "Hello Rust World!" 26 | -------------------------------------------------------------------------------- /Chapter 10/code/read_files_in_dir.rs: -------------------------------------------------------------------------------- 1 | use std::env; 2 | use std::fs; 3 | use std::error::Error; 4 | 5 | fn main() { 6 | show_dir().unwrap(); 7 | } 8 | 9 | fn show_dir() -> Result<(), Box> { 10 | let here = try!(env::current_dir()); 11 | println!("Contents in: {}", here.display()); 12 | for entry in try!(fs::read_dir(&here)) { 13 | let path = try!(entry).path(); 14 | let md = try!(fs::metadata(&path)); 15 | println!(" {} ({} bytes)", path.display(), md.len()); 16 | } 17 | Ok(()) 18 | } 19 | // Contents in: F:\Rust\Rust book\The Rust Programming Language\Chapter 10 - Working with files\code 20 | // F:\Rust\Rust book\The Rust Programming Language\Chapter 10 - Working with files\code\read_file.rs (710 bytes) 21 | // F:\Rust\Rust book\The Rust Programming Language\Chapter 10 - Working with files\code\read_files_in_dir.exe (2382143 bytes) 22 | // F:\Rust\Rust book\The Rust Programming Language\Chapter 10 - Working with files\code\read_files_in_dir.rs (449 bytes) 23 | // F:\Rust\Rust book\The Rust Programming Language\Chapter 10 - Working with files\code\read_file_try.exe (2393158 bytes) 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Chapter 10/code/reading_text_file.rs: -------------------------------------------------------------------------------- 1 | use std::io::{BufRead, BufReader}; 2 | use std::fs::File; 3 | 4 | fn main() { 5 | let file = BufReader::new(File::open("numbers.txt").unwrap()); 6 | 7 | // .lines() eats EOF error, so this is will only panic if something went completely wrong. 8 | let pairs: Vec<_> = file.lines().map(|line| { 9 | let line = line.unwrap(); 10 | let line = line.trim(); 11 | let mut words = line.split(" "); 12 | let left = words.next().expect("Unexpected empty line!"); 13 | let right = words.next().expect("Expected number!"); 14 | 15 | ( 16 | left.parse::().ok().expect("Expected integer in first column!"), 17 | right.parse::().ok().expect("Expected float in second column!") 18 | ) 19 | }).collect(); 20 | 21 | println!("{:?}", pairs); 22 | } 23 | // [(120, 345.56), (125, 341.56)] 24 | -------------------------------------------------------------------------------- /Chapter 10/code/write_file.rs: -------------------------------------------------------------------------------- 1 | static CONTENT: &'static str = 2 | "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod 3 | tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, 4 | quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo 5 | consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse 6 | cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non 7 | proident, sunt in culpa qui officia deserunt mollit anim id est laborum. 8 | "; 9 | 10 | use std::path::Path; 11 | use std::fs::File; 12 | use std::io::prelude::*; 13 | use std::error::Error; 14 | 15 | fn main() { 16 | let path = Path::new("lorem_ipsum.txt"); 17 | let display = path.display(); 18 | 19 | let mut file = match File::create(&path) { 20 | Err(why) => panic!("couldn't create {}: {}", 21 | display, 22 | Error::description(&why)), 23 | Ok(file) => file, 24 | }; 25 | 26 | // variant which does not exit: 27 | // let mut file = match File::create(&path) { 28 | // Err(why) => { println!("couldn't create {}: {}", 29 | // display, 30 | // Error::description(&why)); 31 | // return 32 | // }, 33 | // Ok(file) => file, 34 | // }; 35 | 36 | match file.write_all(CONTENT.as_bytes()) { 37 | Err(why) => { 38 | panic!("couldn't write to {}: {}", 39 | display, 40 | Error::description(&why)) 41 | }, 42 | Ok(_) => println!("successfully wrote to {}", display), 43 | } 44 | 45 | // variant with if-test on successfull write: 46 | if file.write(CONTENT.as_bytes()).is_err() { // error-text not available anymore 47 | println!("Failed to save response."); 48 | return; 49 | } 50 | 51 | 52 | } 53 | // successfully wrote to lorem_ipsum.txt 54 | -------------------------------------------------------------------------------- /Chapter 10/code/write_file_try.rs: -------------------------------------------------------------------------------- 1 | use std::path::Path; 2 | use std::fs::File; 3 | use std::io::prelude::*; 4 | use std::error::Error; 5 | use std::io; 6 | 7 | struct Info { 8 | name: String, 9 | age: i32, 10 | rating: i32 11 | } 12 | 13 | impl Info { 14 | fn as_bytes(&self) -> &[u8] { 15 | self.name.as_bytes() 16 | } 17 | 18 | fn format(&self) -> String { 19 | format!("{};{};{}\n", self.name, self.age, self.rating) 20 | } 21 | } 22 | 23 | fn main() { 24 | let path = Path::new("info.txt"); 25 | let display = path.display(); 26 | 27 | let file = match write_file(&path) { 28 | Err(why) => panic!("couldn't write info to file {}: {}", 29 | display, 30 | Error::description(&why)), 31 | Ok(file) => file, 32 | }; 33 | } 34 | 35 | fn write_file(path: &Path) -> Result { 36 | let mut file = try!(File::create(path)); 37 | let info1 = Info { name:"Barak".to_string(), age: 56, rating: 8 }; 38 | let info2 = Info { name:"Vladimir".to_string(), age: 55, rating: 6 }; 39 | try!(file.write(info1.as_bytes())); 40 | try!(file.write(b"\r\n")); 41 | try!(file.write(info2.as_bytes())); 42 | Ok(file) 43 | } 44 | -------------------------------------------------------------------------------- /Chapter 2/code/alias.rs: -------------------------------------------------------------------------------- 1 | type MagicPower = u16; 2 | 3 | fn main() { 4 | let run: MagicPower = 7800; 5 | } -------------------------------------------------------------------------------- /Chapter 2/code/bindings.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 = 5usize; // 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 | 12 | let energy = "Abundant"; // a new energy variable 13 | // an _ can be used to separate the digits from the type to improve readability: 14 | // let magic_number = 3.14_f32; 15 | let empty = (); // the value of the unit type () 16 | 17 | // changing values: 18 | // energy = 25; // error: re-assignment of immutable variable `energy` 19 | let mut fuel = 34; 20 | fuel = 60; 21 | 22 | let n; // error: unable to infer enough type information about `_`; type annotations required 23 | // println!("n is: {}", n); // error: use of possibly uninitialized variable 24 | n = -2; 25 | let n: i32; 26 | // let n: i32 = -2; // n is a binding of type i32 and the value -2 27 | let x = 42u8; 28 | let magic_number = 3.14f64; 29 | } -------------------------------------------------------------------------------- /Chapter 2/code/comments.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/code/constants1.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/code/constants2.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 | println!( "Two written in binary is {0:b}", 2); 17 | 18 | println!("pi is {:e} in floating point notation", PI); 19 | 20 | let long_decimal : f64 = 0.56545874854551248754; 21 | println!("{:.3}", long_decimal); // 0.565 22 | 23 | let number = 42i32; 24 | println!("{:08}", number); // 00000042 25 | println!("{:8}", number); // 42 26 | 27 | let str = format!("You have {points} % health", points=70); 28 | println!("{}", str); // str now contains the value "You have 70 % health" 29 | } 30 | // The Game you are playing is called Monster Attack. 31 | // You start with 100 health points. 32 | // In the Game Monster Attack you start with 100 % health, yes you heard it correct: 100 points! 33 | // You have 70 % health 34 | // MAX_HEALTH is 64 in hexadecimal 35 | // MAX_HEALTH is 1100100 in binary 36 | // Two written in binary is 10 37 | // pi is 3.14e0 in floating point notation 38 | // 0.565 39 | // 00000042 40 | // 42 41 | // You have 70 % health -------------------------------------------------------------------------------- /Chapter 2/code/expressions.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/code/mutable_constant.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/code/references.rs: -------------------------------------------------------------------------------- 1 | // #![feature(box_syntax)] // error: unstable feature in stable releases 2 | 3 | fn main() { 4 | let health = 32; 5 | let mut game = "Space Invaders"; 6 | println!("address of health-value: {:p}", &health); // prints 0x23fba4 7 | println!("address of game-value: {:p}", &game); // prints 0x23fb90 8 | println!("game-value: {}", game); // prints "Space Invaders" 9 | println!("game: {}", &game); // prints "Space Invaders" 10 | 11 | let game2 = &game; 12 | println!("{:p}", game2); // prints 0x23fb90 13 | println!("{}", *game2); // prints "Space Invaders" 14 | println!("{}", game2); // prints "Space Invaders" 15 | 16 | let x: &i64; 17 | // println!("{:?}", x); // error: use of possibly uninitialized variable: `x` 18 | 19 | // health = 33; // error: re-assignment of immutable variable `health` 20 | let y = &health; 21 | // now *y is the value 32 22 | 23 | // references to an immutable variable: 24 | let tricks = 10; 25 | // let reftricks = &mut tricks; // error: cannot borrow immutable local variable `tricks` as mutable 26 | 27 | // references to a mutable variable: 28 | let mut score = 0; 29 | let score2 = &score; 30 | // *score2 = 5; // cannot assign to immutable borrowed content *score2 31 | 32 | let mut score = 0; 33 | let score3 = &mut score; 34 | *score3 = 5; 35 | 36 | // let score4 = &mut score; 37 | // error: cannot borrow `score` as mutable more than once at a time 38 | 39 | // boxing values onto the heap: 40 | let x = Box::new(5i32); 41 | // let y = box 6; // error: box expression syntax is experimental; you can call `Box::new` instead. 42 | // or use feature gate #![feature(box_syntax)] 43 | // let x = box 5i32; 44 | 45 | } 46 | // address of health-value: 0x23fb04 47 | // address of game-value: 0x23faf0 48 | // game-value: Space Invaders 49 | // game: Space Invaders 50 | // 0x23faf0 51 | // Space Invaders 52 | // Space Invaders -------------------------------------------------------------------------------- /Chapter 2/code/scope.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/code/test.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | // Using local inference, the compiler knows that `elem` has type u64 (machine-dependent) 3 | let elem = 42; 4 | // Create an empty vector (a growable array) 5 | let mut vec = Vec::new(); 6 | // At this point the compiler doesn't know the exact type of `vec`, it 7 | // just knows that it's a vector of something (`Vec<_>`) 8 | // Insert `elem` in the vector 9 | vec.push(elem); 10 | // Aha! Now the compiler knows that `vec` is a vector of `u8`s (`Vec`) 11 | // Try commenting out the `vec.push(elem)` line 12 | // --> error: unable to infer enough type information about `_`; type annotations required [E0282] 13 | println!("{:?}", vec); 14 | } 15 | // [42] 16 | -------------------------------------------------------------------------------- /Chapter 2/code/type_conversions.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/code/type_errors.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/code/types2.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let x = 42u8; 3 | let magic_number = 3.14f64; 4 | } -------------------------------------------------------------------------------- /Chapter 2/exercises/change_constant.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/compound_let.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let mut a = 5; 3 | let mut b = 6; 4 | let n = 7; 5 | 6 | let a = b = n; 7 | println!("{:?}{:?}{:?}", a, b, n); // ()77 8 | // error: the trait `core::fmt::Display` is not implemented for the type `()` [E0277] 9 | // println!("{}{}{}", a, b, n); 10 | 11 | // no swap : 12 | let mut c = 5; 13 | let mut d = 6; 14 | let c = d = c; 15 | println!("{:?}{:?}", c, d); // ()5 16 | } 17 | // a gets the value of the expression: b = n; 18 | // the value of that expression is () 19 | // ()77 20 | // ()5 -------------------------------------------------------------------------------- /Chapter 2/exercises/formatting.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/code/attributes_cfg.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/code/attributes_testing.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/code/doc/.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ivo-Balbaert/start_rust/58531d58b4950420b345f04c4e2d4e5aeb164c0e/Chapter 3/code/doc/.lock -------------------------------------------------------------------------------- /Chapter 3/code/doc/FiraSans-Medium.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ivo-Balbaert/start_rust/58531d58b4950420b345f04c4e2d4e5aeb164c0e/Chapter 3/code/doc/FiraSans-Medium.woff -------------------------------------------------------------------------------- /Chapter 3/code/doc/FiraSans-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ivo-Balbaert/start_rust/58531d58b4950420b345f04c4e2d4e5aeb164c0e/Chapter 3/code/doc/FiraSans-Regular.woff -------------------------------------------------------------------------------- /Chapter 3/code/doc/Heuristica-Italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ivo-Balbaert/start_rust/58531d58b4950420b345f04c4e2d4e5aeb164c0e/Chapter 3/code/doc/Heuristica-Italic.woff -------------------------------------------------------------------------------- /Chapter 3/code/doc/SourceCodePro-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ivo-Balbaert/start_rust/58531d58b4950420b345f04c4e2d4e5aeb164c0e/Chapter 3/code/doc/SourceCodePro-Regular.woff -------------------------------------------------------------------------------- /Chapter 3/code/doc/SourceCodePro-Semibold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ivo-Balbaert/start_rust/58531d58b4950420b345f04c4e2d4e5aeb164c0e/Chapter 3/code/doc/SourceCodePro-Semibold.woff -------------------------------------------------------------------------------- /Chapter 3/code/doc/SourceSerifPro-Bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ivo-Balbaert/start_rust/58531d58b4950420b345f04c4e2d4e5aeb164c0e/Chapter 3/code/doc/SourceSerifPro-Bold.woff -------------------------------------------------------------------------------- /Chapter 3/code/doc/SourceSerifPro-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ivo-Balbaert/start_rust/58531d58b4950420b345f04c4e2d4e5aeb164c0e/Chapter 3/code/doc/SourceSerifPro-Regular.woff -------------------------------------------------------------------------------- /Chapter 3/code/doc/exdoc/fn.cube.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | exdoc::cube - Rust 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 24 | 25 | 26 | 27 | 31 | 32 | 42 | 43 |
44 |

Function exdoc::cube 45 | [-] [+] 46 | [src]

47 |
pub fn cube(val: u32) -> u32

Calculates the cube val * val * val.

48 | 49 |

Examples

 51 | let cube = cube(val);
 52 | 
53 |
54 | 55 | 56 | 57 | 58 | 88 | 89 | 90 | 91 | 96 | 97 | 98 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /Chapter 3/code/doc/exdoc/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | exdoc - Rust 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 24 | 25 | 26 | 27 | 31 | 32 | 42 | 43 |
44 |

Crate exdoc[stability] 45 | [-] [+] 46 | [src]

47 |

Functions

48 | 49 | 50 | 52 | 54 | 55 |
cube

Calculates the cube val * val * val.

53 |
56 | 57 | 58 | 59 | 60 | 90 | 91 | 92 | 93 | 98 | 99 | 100 | 101 | 102 | 103 | -------------------------------------------------------------------------------- /Chapter 3/code/doc/exdoc/sidebar-items.js: -------------------------------------------------------------------------------- 1 | initSidebarItems({"fn":[["cube","Calculates the cube `val * val * val`."]]}); -------------------------------------------------------------------------------- /Chapter 3/code/doc/exdoc/stability.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | exdoc - Stability dashboard 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 24 | 25 | 26 | 27 | 31 | 32 | 42 | 43 |

Stability dashboard: crate exdoc

44 | This dashboard summarizes the stability levels for all of the public modules of 45 | the crate, according to the total number of items at each level in the module and 46 | its children (percentages total for exdoc): 47 |
48 | stable (0%),
49 | unstable (0%),
50 | deprecated (0%),
51 | unmarked (100%) 52 |
53 | The counts do not include methods or trait 54 | implementations that are visible only through a re-exported type.
exdoc    
55 | 56 | 57 | 58 | 59 | 89 | 90 | 91 | 92 | 97 | 98 | 99 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /Chapter 3/code/doc/exdoc/stability.json: -------------------------------------------------------------------------------- 1 | {"name":"exdoc","counts":{"deprecated":0,"unstable":0,"stable":0,"unmarked":2},"submodules":[]} -------------------------------------------------------------------------------- /Chapter 3/code/doc/main.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2013 The Rust Project Developers. See the COPYRIGHT 3 | * file at the top-level directory of this distribution and at 4 | * http://rust-lang.org/COPYRIGHT. 5 | * 6 | * Licensed under the Apache License, Version 2.0 or the MIT license 8 | * , at your 9 | * option. This file may not be copied, modified, or distributed 10 | * except according to those terms. 11 | */ 12 | @font-face { 13 | font-family: 'Fira Sans'; 14 | font-style: normal; 15 | font-weight: 400; 16 | src: local('Fira Sans'), url("FiraSans-Regular.woff") format('woff'); 17 | } 18 | @font-face { 19 | font-family: 'Fira Sans'; 20 | font-style: normal; 21 | font-weight: 500; 22 | src: local('Fira Sans Medium'), url("FiraSans-Medium.woff") format('woff'); 23 | } 24 | @font-face { 25 | font-family: 'Source Serif Pro'; 26 | font-style: normal; 27 | font-weight: 400; 28 | src: local('Source Serif Pro'), url("SourceSerifPro-Regular.woff") format('woff'); 29 | } 30 | @font-face { 31 | font-family: 'Source Serif Pro'; 32 | font-style: italic; 33 | font-weight: 400; 34 | src: url("Heuristica-Italic.woff") format('woff'); 35 | } 36 | @font-face { 37 | font-family: 'Source Serif Pro'; 38 | font-style: normal; 39 | font-weight: 700; 40 | src: local('Source Serif Pro Bold'), url("SourceSerifPro-Bold.woff") format('woff'); 41 | } 42 | @font-face { 43 | font-family: 'Source Code Pro'; 44 | font-style: normal; 45 | font-weight: 400; 46 | src: local('Source Code Pro'), url("SourceCodePro-Regular.woff") format('woff'); 47 | } 48 | @font-face { 49 | font-family: 'Source Code Pro'; 50 | font-style: normal; 51 | font-weight: 600; 52 | src: local('Source Code Pro Semibold'), url("SourceCodePro-Semibold.woff") format('woff'); 53 | } 54 | 55 | @import "normalize.css"; 56 | 57 | * { 58 | -webkit-box-sizing: border-box; 59 | -moz-box-sizing: border-box; 60 | box-sizing: border-box; 61 | } 62 | 63 | /* General structure and fonts */ 64 | 65 | body { 66 | color: #333; 67 | font: 16px/1.4 "Source Serif Pro", Georgia, Times, "Times New Roman", serif; 68 | margin: 0; 69 | position: relative; 70 | padding: 10px 15px 20px 15px; 71 | 72 | -webkit-font-feature-settings: "kern", "liga"; 73 | -moz-font-feature-settings: "kern", "liga"; 74 | font-feature-settings: "kern", "liga"; 75 | } 76 | 77 | h1 { 78 | font-size: 1.5em; 79 | } 80 | h2 { 81 | font-size: 1.4em; 82 | } 83 | h3 { 84 | font-size: 1.3em; 85 | } 86 | h1, h2, h3:not(.impl):not(.method):not(.type):not(.tymethod), h4:not(.method):not(.type):not(.tymethod) { 87 | color: black; 88 | font-weight: 500; 89 | margin: 20px 0 15px 0; 90 | padding-bottom: 6px; 91 | } 92 | h1.fqn { 93 | border-bottom: 1px dashed #D5D5D5; 94 | margin-top: 0; 95 | } 96 | h2, h3:not(.impl):not(.method):not(.type):not(.tymethod), h4:not(.method):not(.type):not(.tymethod) { 97 | border-bottom: 1px solid #DDDDDD; 98 | } 99 | h3.impl, h3.method, h4.method, h3.type, h4.type { 100 | font-weight: 600; 101 | margin-top: 10px; 102 | margin-bottom: 10px; 103 | } 104 | h3.impl, h3.method, h3.type { 105 | margin-top: 15px; 106 | } 107 | h1, h2, h3, h4, section.sidebar, a.source, .search-input, .content table :not(code)>a, .collapse-toggle { 108 | font-family: "Fira Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; 109 | } 110 | 111 | ol, ul { 112 | padding-left: 25px; 113 | } 114 | ul ul, ol ul, ul ol, ol ol { 115 | margin-bottom: 0; 116 | } 117 | 118 | p { 119 | margin: 0 0 .6em 0; 120 | } 121 | 122 | code, pre { 123 | font-family: "Source Code Pro", Menlo, Monaco, Consolas, "DejaVu Sans Mono", Inconsolata, monospace; 124 | white-space: pre-wrap; 125 | } 126 | .docblock code { 127 | background-color: #F5F5F5; 128 | border-radius: 3px; 129 | padding: 0 0.2em; 130 | } 131 | pre { 132 | background-color: #F5F5F5; 133 | padding: 14px; 134 | } 135 | 136 | .source pre { 137 | padding: 20px; 138 | } 139 | 140 | .content.source { 141 | margin-top: 50px; 142 | max-width: none; 143 | overflow: visible; 144 | margin-left: 0px; 145 | min-width: 70em; 146 | } 147 | 148 | nav.sub { 149 | font-size: 16px; 150 | text-transform: uppercase; 151 | } 152 | 153 | .sidebar { 154 | width: 200px; 155 | position: absolute; 156 | left: 0; 157 | top: 0; 158 | min-height: 100%; 159 | } 160 | 161 | .content, nav { max-width: 960px; } 162 | 163 | /* Everything else */ 164 | 165 | .js-only, .hidden { display: none; } 166 | 167 | .sidebar { 168 | padding: 10px; 169 | } 170 | .sidebar img { 171 | margin: 20px auto; 172 | display: block; 173 | } 174 | 175 | .sidebar .location { 176 | font-size: 17px; 177 | margin: 30px 0 20px 0; 178 | background: #e1e1e1; 179 | text-align: center; 180 | color: #333; 181 | } 182 | 183 | .location a:first-child { font-weight: 500; } 184 | 185 | .block { 186 | padding: 0 10px; 187 | margin-bottom: 14px; 188 | } 189 | .block h2 { 190 | margin-top: 0; 191 | margin-bottom: 8px; 192 | text-align: center; 193 | } 194 | 195 | .block a { 196 | display: block; 197 | text-overflow: ellipsis; 198 | overflow: hidden; 199 | line-height: 15px; 200 | padding: 7px 5px; 201 | font-size: 14px; 202 | font-weight: 300; 203 | transition: border 500ms ease-out; 204 | } 205 | 206 | .block a:hover { 207 | background: #F5F5F5; 208 | } 209 | 210 | .content { 211 | padding: 15px 0; 212 | } 213 | 214 | .content.source pre.rust { 215 | white-space: pre; 216 | overflow: auto; 217 | padding-left: 0; 218 | } 219 | .content pre.line-numbers { 220 | float: left; 221 | border: none; 222 | position: relative; 223 | 224 | -webkit-user-select: none; 225 | -moz-user-select: none; 226 | -ms-user-select: none; 227 | user-select: none; 228 | } 229 | .line-numbers span { color: #c67e2d; cursor: pointer; } 230 | .line-numbers .line-highlighted { 231 | background-color: #f6fdb0 !important; 232 | } 233 | 234 | .content .highlighted { 235 | color: #000 !important; 236 | background-color: #ccc; 237 | } 238 | .content .highlighted a, .content .highlighted span { color: #000 !important; } 239 | .content .highlighted.trait { background-color: #fece7e; } 240 | .content .highlighted.mod { background-color: #afc6e4; } 241 | .content .highlighted.enum { background-color: #b4d1b9; } 242 | .content .highlighted.struct { background-color: #e7b1a0; } 243 | .content .highlighted.fn { background-color: #c6afb3; } 244 | .content .highlighted.method { background-color: #c6afb3; } 245 | .content .highlighted.tymethod { background-color: #c6afb3; } 246 | .content .highlighted.type { background-color: #c6afb3; } 247 | 248 | .docblock.short.nowrap { 249 | display: block; 250 | overflow: hidden; 251 | white-space: nowrap; 252 | text-overflow: ellipsis; 253 | } 254 | 255 | .docblock.short p { 256 | overflow: hidden; 257 | text-overflow: ellipsis; 258 | margin: 0; 259 | } 260 | .docblock.short code { white-space: nowrap; } 261 | 262 | .docblock h1, .docblock h2, .docblock h3, .docblock h4, .docblock h5 { 263 | border-bottom: 1px solid #DDD; 264 | } 265 | 266 | .docblock h1 { font-size: 1.3em; } 267 | .docblock h2 { font-size: 1.15em; } 268 | .docblock h3, .docblock h4, .docblock h5 { font-size: 1em; } 269 | 270 | .content .out-of-band { 271 | font-size: 23px; 272 | width: 40%; 273 | margin: 0px; 274 | padding: 0px; 275 | text-align: right; 276 | display: inline-block; 277 | } 278 | 279 | .content .in-band { 280 | width: 60%; 281 | margin: 0px; 282 | padding: 0px; 283 | display: inline-block; 284 | } 285 | 286 | .content table { 287 | border-spacing: 0 5px; 288 | border-collapse: separate; 289 | } 290 | .content td { vertical-align: top; } 291 | .content td:first-child { padding-right: 20px; } 292 | .content td p:first-child { margin-top: 0; } 293 | .content td h1, .content td h2 { margin-left: 0; font-size: 1.1em; } 294 | 295 | .docblock table { 296 | border: 1px solid #ddd; 297 | margin: .5em 0; 298 | border-collapse: collapse; 299 | width: 100%; 300 | } 301 | 302 | .docblock table td { 303 | padding: .5em; 304 | border-top: 1px dashed #ddd; 305 | border-bottom: 1px dashed #ddd; 306 | 307 | } 308 | 309 | .docblock table th { 310 | padding: .5em; 311 | text-align: left; 312 | border-top: 1px solid #ddd; 313 | border-bottom: 1px solid #ddd; 314 | } 315 | 316 | .content .item-list { 317 | list-style-type: none; 318 | padding: 0; 319 | } 320 | 321 | .content .item-list li { margin-bottom: 3px; } 322 | 323 | .content .multi-column { 324 | -moz-column-count: 5; 325 | -moz-column-gap: 2.5em; 326 | -webkit-column-count: 5; 327 | -webkit-column-gap: 2.5em; 328 | column-count: 5; 329 | column-gap: 2.5em; 330 | } 331 | .content .multi-column li { width: 100%; display: inline-block; } 332 | 333 | .content .method { 334 | font-size: 1em; 335 | position: relative; 336 | } 337 | /* Shift "where ..." part of method definition down a line */ 338 | .content .method .where { display: block; } 339 | /* Bit of whitespace to indent it */ 340 | .content .method .where::before { content: ' '; } 341 | 342 | .content .methods .docblock { margin-left: 40px; } 343 | 344 | .content .impl-items .docblock { margin-left: 40px; } 345 | 346 | nav { 347 | border-bottom: 1px solid #e0e0e0; 348 | padding-bottom: 10px; 349 | margin-bottom: 10px; 350 | } 351 | nav.main { 352 | padding: 20px 0; 353 | text-align: center; 354 | } 355 | nav.main .current { 356 | border-top: 1px solid #000; 357 | border-bottom: 1px solid #000; 358 | } 359 | nav.main .separator { 360 | border: 1px solid #000; 361 | display: inline-block; 362 | height: 23px; 363 | margin: 0 20px; 364 | } 365 | nav.sum { text-align: right; } 366 | nav.sub form { display: inline; } 367 | 368 | nav, .content { 369 | margin-left: 230px; 370 | } 371 | 372 | a { 373 | text-decoration: none; 374 | color: #000; 375 | background: transparent; 376 | } 377 | 378 | .docblock a { 379 | color: #4e8bca; 380 | } 381 | 382 | .docblock a:hover { 383 | text-decoration: underline; 384 | } 385 | 386 | .content span.trait, .content a.trait, .block a.current.trait { color: #ed9603; } 387 | .content span.mod, .content a.mod, block a.current.mod { color: #4d76ae; } 388 | .content span.enum, .content a.enum, .block a.current.enum { color: #5e9766; } 389 | .content span.struct, .content a.struct, .block a.current.struct { color: #e53700; } 390 | .content span.fn, .content a.fn, .block a.current.fn { color: #8c6067; } 391 | .content span.method, .content a.method, .block a.current.method { color: #8c6067; } 392 | .content span.tymethod, .content a.tymethod, .block a.current.tymethod { color: #8c6067; } 393 | .content .fnname { color: #8c6067; } 394 | 395 | .search-input { 396 | width: 100%; 397 | /* Override Normalize.css: we have margins and do 398 | not want to overflow - the `moz` attribute is necessary 399 | until Firefox 29, too early to drop at this point */ 400 | -moz-box-sizing: border-box !important; 401 | box-sizing: border-box !important; 402 | outline: none; 403 | border: none; 404 | border-radius: 1px; 405 | color: #555; 406 | margin-top: 5px; 407 | padding: 10px 16px; 408 | font-size: 17px; 409 | box-shadow: 0 0 0 1px #e0e0e0, 0 0 0 2px transparent; 410 | transition: border-color 300ms ease; 411 | transition: border-radius 300ms ease-in-out; 412 | transition: box-shadow 300ms ease-in-out; 413 | } 414 | 415 | .search-input:focus { 416 | border-color: #66afe9; 417 | border-radius: 2px; 418 | border: 0; 419 | outline: 0; 420 | box-shadow: 0 0 8px #078dd8; 421 | } 422 | 423 | .search-results .desc { 424 | white-space: nowrap; 425 | text-overflow: ellipsis; 426 | overflow: hidden; 427 | display: block; 428 | } 429 | 430 | .search-results a { 431 | display: block; 432 | } 433 | 434 | .content .search-results td:first-child { padding-right: 0; } 435 | .content .search-results td:first-child a { padding-right: 10px; } 436 | 437 | #help { 438 | background: #e9e9e9; 439 | border-radius: 4px; 440 | box-shadow: 0 0 6px rgba(0,0,0,.2); 441 | position: absolute; 442 | top: 300px; 443 | left: 50%; 444 | margin-top: -125px; 445 | margin-left: -275px; 446 | width: 550px; 447 | height: 300px; 448 | border: 1px solid #bfbfbf; 449 | } 450 | 451 | #help dt { 452 | float: left; 453 | border-radius: 3px; 454 | border: 1px solid #bfbfbf; 455 | background: #fff; 456 | width: 23px; 457 | text-align: center; 458 | clear: left; 459 | display: block; 460 | margin-top: -1px; 461 | } 462 | #help dd { margin: 5px 33px; } 463 | #help .infos { padding-left: 0; } 464 | #help h1 { margin-top: 0; } 465 | #help div { 466 | width: 50%; 467 | float: left; 468 | padding: 20px; 469 | } 470 | 471 | .stability { 472 | border-left: 6px solid; 473 | padding: 3px 6px; 474 | border-radius: 3px; 475 | } 476 | 477 | h1 .stability { 478 | text-transform: lowercase; 479 | font-weight: 400; 480 | margin-left: 14px; 481 | padding: 4px 10px; 482 | } 483 | 484 | .impl-items .stability, .methods .stability { 485 | margin-right: 20px; 486 | } 487 | 488 | .stability.Deprecated { border-color: #A071A8; color: #82478C; } 489 | .stability.Experimental { border-color: #D46D6A; color: #AA3C39; } 490 | .stability.Unstable { border-color: #D4B16A; color: #AA8439; } 491 | .stability.Stable { border-color: #54A759; color: #2D8632; } 492 | .stability.Frozen { border-color: #009431; color: #007726; } 493 | .stability.Locked { border-color: #0084B6; color: #00668c; } 494 | .stability.Unmarked { border-color: #BBBBBB; } 495 | 496 | .summary { 497 | padding-right: 0px; 498 | } 499 | .summary.Deprecated { background-color: #A071A8; } 500 | .summary.Experimental { background-color: #D46D6A; } 501 | .summary.Unstable { background-color: #D4B16A; } 502 | .summary.Stable { background-color: #54A759; } 503 | .summary.Unmarked { background-color: #BBBBBB; } 504 | 505 | :target { background: #FDFFD3; } 506 | .line-numbers :target { background-color: transparent; } 507 | 508 | /* Code highlighting */ 509 | pre.rust .kw { color: #8959A8; } 510 | pre.rust .kw-2, pre.rust .prelude-ty { color: #4271AE; } 511 | pre.rust .number, pre.rust .string { color: #718C00; } 512 | pre.rust .self, pre.rust .boolval, pre.rust .prelude-val, 513 | pre.rust .attribute, pre.rust .attribute .ident { color: #C82829; } 514 | pre.rust .comment { color: #8E908C; } 515 | pre.rust .doccomment { color: #4D4D4C; } 516 | pre.rust .macro, pre.rust .macro-nonterminal { color: #3E999F; } 517 | pre.rust .lifetime { color: #B76514; } 518 | 519 | .rusttest { display: none; } 520 | pre.rust { position: relative; } 521 | .test-arrow { 522 | display: inline-block; 523 | position: absolute; 524 | top: 0; 525 | right: 10px; 526 | font-size: 150%; 527 | -webkit-transform: scaleX(-1); 528 | transform: scaleX(-1); 529 | } 530 | 531 | .methods .section-header { 532 | /* Override parent class attributes. */ 533 | border-bottom: none !important; 534 | font-size: 1.1em !important; 535 | margin: 0 0 -5px; 536 | padding: 0; 537 | } 538 | 539 | .section-header:hover a:after { 540 | content: '\2002\00a7\2002'; 541 | } 542 | 543 | .section-header:hover a { 544 | text-decoration: none; 545 | } 546 | 547 | .section-header a { 548 | color: inherit; 549 | } 550 | 551 | .collapse-toggle { 552 | font-weight: 300; 553 | position: absolute; 554 | left: 13px; 555 | color: #999; 556 | margin-top: 2px; 557 | } 558 | 559 | .toggle-wrapper > .collapse-toggle { 560 | left: -24px; 561 | margin-top: 0px; 562 | } 563 | 564 | .toggle-wrapper { 565 | position: relative; 566 | } 567 | 568 | .toggle-wrapper.collapsed { 569 | height: 1em; 570 | transition: height .2s; 571 | } 572 | 573 | .collapse-toggle > .inner { 574 | display: inline-block; 575 | width: 1ch; 576 | text-align: center; 577 | } 578 | 579 | .toggle-label { 580 | color: #999; 581 | } 582 | 583 | 584 | 585 | /* Media Queries */ 586 | 587 | @media (max-width: 700px) { 588 | body { 589 | padding-top: 0px; 590 | } 591 | 592 | .sidebar { 593 | height: 40px; 594 | min-height: 40px; 595 | width: 100%; 596 | margin: 0px; 597 | padding: 0px; 598 | position: static; 599 | } 600 | 601 | .sidebar .location { 602 | float: left; 603 | margin: 0px; 604 | padding: 5px; 605 | width: 60%; 606 | background: inherit; 607 | text-align: left; 608 | font-size: 24px; 609 | } 610 | 611 | .sidebar img { 612 | width: 35px; 613 | margin-top: 5px; 614 | margin-bottom: 0px; 615 | float: left; 616 | } 617 | 618 | nav.sub { 619 | margin: 0 auto; 620 | } 621 | 622 | .sidebar .block { 623 | display: none; 624 | } 625 | 626 | .content { 627 | margin-left: 0px; 628 | } 629 | 630 | .content .in-band { 631 | width: 100%; 632 | } 633 | 634 | .content .out-of-band { 635 | display: none; 636 | } 637 | 638 | .toggle-wrapper > .collapse-toggle { 639 | left: 0px; 640 | } 641 | 642 | .toggle-wrapper { 643 | height: 1.5em; 644 | } 645 | } 646 | 647 | @media print { 648 | nav.sub, .content .out-of-band, .collapse-toggle { 649 | display: none; 650 | } 651 | } 652 | -------------------------------------------------------------------------------- /Chapter 3/code/doc/normalize.css: -------------------------------------------------------------------------------- 1 | /*! normalize.css v3.0.0 | MIT License | git.io/normalize */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{height:auto}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:bold}table{border-collapse:collapse;border-spacing:0}td,th{padding:0} 2 | -------------------------------------------------------------------------------- /Chapter 3/code/doc/playpen.js: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Rust Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution and at 3 | // http://rust-lang.org/COPYRIGHT. 4 | // 5 | // Licensed under the Apache License, Version 2.0 or the MIT license 7 | // , at your 8 | // option. This file may not be copied, modified, or distributed 9 | // except according to those terms. 10 | 11 | /*jslint browser: true, es5: true */ 12 | /*globals $: true, rootPath: true */ 13 | 14 | (function() { 15 | if (window.playgroundUrl) { 16 | $('pre.rust').hover(function() { 17 | var a = $('').text('⇱').attr('class', 'test-arrow'); 18 | var code = $(this).prev(".rusttest").text(); 19 | a.attr('href', window.playgroundUrl + '?code=' + 20 | encodeURIComponent(code)); 21 | a.attr('target', '_blank'); 22 | $(this).append(a); 23 | }, function() { 24 | $(this).find('a.test-arrow').remove(); 25 | }); 26 | } 27 | }()); 28 | 29 | -------------------------------------------------------------------------------- /Chapter 3/code/doc/search-index.js: -------------------------------------------------------------------------------- 1 | var searchIndex = {}; 2 | searchIndex['exdoc'] = {"items":[[0,"","exdoc","",null,null],[5,"cube","","Calculates the cube `val * val * val`.",null,{"inputs":[{"name":"u32"}],"output":{"name":"u32"}}]],"paths":[]}; 3 | initSearch(searchIndex); 4 | -------------------------------------------------------------------------------- /Chapter 3/code/doc/src/exdoc/exdoc.rs/exdoc.rs.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | exdoc.rs.html -- source 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 24 | 25 | 26 | 27 | 31 | 32 | 42 | 43 |
 1
 44 |  2
 45 |  3
 46 |  4
 47 |  5
 48 |  6
 49 |  7
 50 |  8
 51 |  9
 52 | 10
 53 | 11
 54 | 12
 55 | 13
 56 | 14
 57 | 15
 58 | 16
 59 | 
 60 | fn main() {
 61 | 	println!("The cube of 4 is {}", cube(4));
 62 | }
 63 | 
 64 | /// Calculates the cube `val * val * val`.
 65 | ///
 66 | /// # Examples
 67 | ///
 68 | /// ```
 69 | /// let cube = cube(val);
 70 | /// ```
 71 | pub fn cube(val: u32) -> u32 {
 72 |     // implementation goes here

 73 |     val * val * val
 74 | }
 75 | // The cube of 4 is 64
 76 | 
77 |
78 | 79 | 80 | 81 | 82 | 112 | 113 | 114 | 115 | 120 | 121 | 122 | 123 | 124 | 125 | -------------------------------------------------------------------------------- /Chapter 3/code/exdoc.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/code/fib_procedural.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let ans = fib(10); 3 | println!("{}", ans); 4 | } 5 | 6 | fn fib(x: i64) -> i64 { 7 | if x == 0 || x == 1 { return x; } 8 | fib(x - 1) + fib(x - 2) 9 | } 10 | // 55 -------------------------------------------------------------------------------- /Chapter 3/code/functions.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let hero1 = "Pac Man"; // is of type &str 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 | println!("{}", double_input(4)); 12 | println!("{}", double_inputs(4)); 13 | } 14 | 15 | fn greet(name: &str) { 16 | println!("Hi mighty {}, what brings you here?", name); 17 | } 18 | 19 | fn greet_both(name1: &str, name2: &str) { 20 | greet(name1); 21 | greet(name2); 22 | } 23 | 24 | fn increment_power(power: i32) -> i32 { 25 | // if power < 100 { return 999; } 26 | println!("My power is going to increase:"); 27 | // power + 1; // results in: error: not all control paths return a value 28 | // return power + 1 // poor style 29 | power + 1 30 | } 31 | 32 | fn double_input(mut i: u32) -> u32 { 33 | i = i * 2; 34 | i 35 | } 36 | 37 | fn double_inputs(i: u32) -> u32 { i * 2 } 38 | 39 | // Hi mighty Riddick, what brings you here? 40 | // Hi mighty Pac Man, what brings you here? 41 | // Hi mighty Riddick, what brings you here? 42 | // My power is going to increase: 43 | // I am now at power level: 2 44 | // 8 45 | -------------------------------------------------------------------------------- /Chapter 3/code/ifelse.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/code/iter_step.rs: -------------------------------------------------------------------------------- 1 | use std::iter; 2 | 3 | fn main() { 4 | for i in iter::range_step(5i32, 0, -1) { 5 | print!("{} - ", i); 6 | } 7 | } 8 | // 5 - 4 - 3 - 2 - 1 - -------------------------------------------------------------------------------- /Chapter 3/code/loops.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/code/mylib/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /Cargo.lock 3 | -------------------------------------------------------------------------------- /Chapter 3/code/mylib/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | 3 | name = "mylib" 4 | version = "0.0.1" 5 | authors = ["Ivo Balbaert "] 6 | -------------------------------------------------------------------------------- /Chapter 3/code/mylib/src/lib.rs: -------------------------------------------------------------------------------- 1 | #[test] 2 | fn it_works() { 3 | } 4 | -------------------------------------------------------------------------------- /Chapter 3/code/nested_function.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | foo(); 3 | } 4 | 5 | fn foo() { 6 | fn bar() { println!("bar"); } 7 | bar(); 8 | } 9 | // bar 10 | -------------------------------------------------------------------------------- /Chapter 3/code/random.rs: -------------------------------------------------------------------------------- 1 | use std::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.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 | // corrected version: 13 | fn abs(x: i32) -> i32 { 14 | if x > 0 { 15 | x 16 | } else { 17 | -x 18 | } 19 | } -------------------------------------------------------------------------------- /Chapter 3/exercises/ifreturn.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.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/code/arrays.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | // arrays: 3 | let aliens = ["Cherfer", "Fynock", "Shirack", "Zuxu"]; 4 | println!("{:?}", aliens); 5 | let aliens: [&str; 4] = ["Cherfer", "Fynock", "Shirack", "Zuxu"]; 6 | // a mutable version: 7 | let mut aliens = ["Cherfer", "Fynock", "Shirack", "Zuxu"]; 8 | let zuxus = ["Zuxu"; 3]; // ["Zuxu", "Zuxu", "Zuxu"]; 9 | 10 | // gotcha: 11 | let mut buffer = [0u8, 255]; 12 | println!("{:?}", buffer ); 13 | let mut buffer = [0u8; 255]; 14 | 15 | // empty array: 16 | let mut empty: [i32; 0] = []; 17 | println!("{:?}", empty); // [] 18 | println!("The first item is: {}", aliens[0]); 19 | println!("The third item is: {}", aliens[2]); 20 | println!("The last item is: {}", aliens[aliens.len() - 1]); 21 | println!("The last item is: {}", aliens.iter().last().unwrap()); 22 | // println!("This item does not exist: {}", aliens[10]); // runtime error: 23 | // thread '
' panicked at 'index out of bounds: the len is 4 but the index is 10' 24 | 25 | // Pointers to arrays use automatic dereferencing: 26 | let pa = &aliens; 27 | println!("Third item via pointer: {}", pa[2]); 28 | 29 | // change an item, but only if array is mutable! 30 | // aliens[2] = "Facehugger"; // error: cannot assign to immutable indexed content `aliens[..]` 31 | println!("Here are the aliens: "); 32 | for ix in 0..aliens.len() { 33 | println!("Alien no {} is {}", ix, aliens[ix]); 34 | } 35 | 36 | for a in aliens.iter() { 37 | println!("The next alien is {}", a); 38 | } 39 | 40 | for a in &aliens { 41 | println!("The next alien is {}", a); 42 | } 43 | 44 | // making vectors: 45 | let mut numbers: Vec = Vec::new(); 46 | // let mut numbers: Vec<_> = Vec::new(); 47 | 48 | let mut magic_numbers = vec![7i32, 42, 47, 45, 54]; 49 | 50 | let mut ids: Vec = Vec::with_capacity(25); 51 | 52 | let rgvec: Vec = (0..7).collect(); 53 | println!("Collected the range into: {:?}", rgvec); 54 | 55 | // push and pop: 56 | numbers.push(magic_numbers[1]); 57 | numbers.push(magic_numbers[4]); 58 | println!("{:?}", numbers); 59 | let fifty_four = numbers.pop(); // fifty_four now contains 54 60 | println!("{:?}", numbers); 61 | 62 | // iterate over a vector: 63 | let values = vec![1, 2, 3]; 64 | for n in values { 65 | println!("{}", n); 66 | } 67 | 68 | // mutate while iterating: 69 | let mut vec = vec![1, 2, 3, 4]; 70 | for x in vec.iter_mut() { 71 | *x += 1; 72 | } 73 | println!("{:?}", vec); 74 | 75 | // slices: 76 | let slc = &magic_numbers[1..4]; // only the items 42, 47 and 45 77 | assert_eq!([42, 47, 45], slc); 78 | 79 | let vec1 = slc.to_vec(); 80 | println!("{:?}", vec1 ); 81 | 82 | println!(""); 83 | // slice from a String: 84 | let location = "Middle-Earth"; 85 | let part = &location[7..12]; 86 | println!("{}", part); // Earth 87 | 88 | // collect: 89 | let magician = "Merlin"; 90 | let mut chars: Vec = magician.chars().collect(); 91 | chars.sort(); 92 | for c in chars { 93 | print!("{} ", c); 94 | } 95 | let v: Vec<&str> = "The wizard of Oz".split(' ').collect(); 96 | assert_eq!(v, vec!["The", "wizard", "of", "Oz"]); 97 | 98 | let v: Vec<&str> = "abc1def2ghi".split(|c: char| c.is_numeric()).collect(); 99 | assert_eq!(v, vec!["abc", "def", "ghi"]); 100 | println!(""); 101 | 102 | // converting from a &str to a &[u8]: 103 | let arr = magician.as_bytes(); 104 | println!("{:?}", arr ); 105 | } 106 | // ["Cherfer", "Fynock", "Shirack", "Zuxu"] 107 | // [0, 255] 108 | // [] 109 | // The first item is: Cherfer 110 | // The third item is: Shirack 111 | // The last item is: Zuxu 112 | // The last item is: Zuxu 113 | // Third item via pointer: Shirack 114 | // Here are the aliens: 115 | // Alien no 0 is Cherfer 116 | // Alien no 1 is Fynock 117 | // Alien no 2 is Shirack 118 | // Alien no 3 is Zuxu 119 | // The next alien is Cherfer 120 | // The next alien is Fynock 121 | // The next alien is Shirack 122 | // The next alien is Zuxu 123 | // Collected the range into: [0, 1, 2, 3, 4, 5, 6] 124 | // [42, 54] 125 | // [42] 126 | // 1 127 | // 2 128 | // 3 129 | // [2, 3, 4, 5] 130 | // [42, 47, 45] 131 | // 132 | // Earth 133 | // M e i l n r 134 | // [77, 101, 114, 108, 105, 110] -------------------------------------------------------------------------------- /Chapter 4/code/destructure_enum.rs: -------------------------------------------------------------------------------- 1 | use En::*; 2 | 3 | struct St { 4 | f1: i32, 5 | f2: f32 6 | } 7 | 8 | enum En { 9 | Var1, 10 | Var2, 11 | Var3(i32), 12 | Var4(i32, St, i32) 13 | } 14 | 15 | fn foo(x: En) { 16 | match x { 17 | Var1 => println!("first variant"), 18 | Var2 => println!("second variant"), 19 | Var3(..) => println!("third variant"), 20 | Var4(..) => println!("fourth variant") 21 | } 22 | } 23 | 24 | fn foo2(x: &En) { 25 | match x { 26 | &Var1 => println!("first variant"), 27 | &Var2 => println!("second variant"), 28 | &Var3(5) => println!("third variant with number 5"), 29 | &Var3(x) => println!("third variant with number {} (not 5)", x), 30 | &Var4(3, St{ f1: 3, f2: x }, 45) => { 31 | println!("destructuring an embedded struct, found {} in f2", x) 32 | } 33 | _ => println!("other (Var4)") 34 | // cannot move out of borrowed content: 35 | // &Var4(_, v, _) => { 36 | // println!("Some other Var4 with {} in f1 and {} in f2", v.f1, v.f2) 37 | // } 38 | // // _ => println!("other (Var2)") // unreachable pattern 39 | } 40 | } 41 | 42 | fn main() { 43 | let en1 = En::Var3(42); 44 | // foo(en1); // third variant 45 | foo2(&en1); // third variant with number 42 (not 5) 46 | let st1 = St { f1: 3, f2: 10.0 }; 47 | // let en2 = En::Var4(3, st1, 45); 48 | // foo2(&en2); // destructuring an embedded struct, found 10 in f2 49 | let en3 = En::Var4(3, st1, 42); 50 | foo2(&en3); // other (Var4) 51 | } 52 | // third variant with number 42 (not 5) 53 | // other (Var4) -------------------------------------------------------------------------------- /Chapter 4/code/destructuring_structs.rs: -------------------------------------------------------------------------------- 1 | struct Big { 2 | field1: i32, 3 | field2: i32, 4 | field3: i32, 5 | field4: i32, 6 | field5: i32, 7 | field6: i32, 8 | field7: i32, 9 | field8: i32, 10 | field9: i32 11 | } 12 | 13 | fn foo(b: Big) { 14 | let Big { field6: x, field3: y, ..} = b; 15 | println!("pulled out {} and {}", x, y); 16 | let Big { field6, field3, ..} = b; 17 | println!("pulled out {} and {}", field3, field6); 18 | let Big { field3: ref x, ref field6, ..} = b; 19 | println!("pulled out {} and {}", *x, *field6); 20 | } 21 | 22 | fn main() { 23 | let big = Big {field1: 1, field2: 2, field3: 3, field4: 4, 24 | field5: 5, field6: 6, field7: 7, field8: 8, field9: 9}; 25 | foo(big); 26 | } 27 | // pulled out 6 and 3 28 | // pulled out 3 and 6 29 | // pulled out 3 and 6 -------------------------------------------------------------------------------- /Chapter 4/code/enums.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/code/enums2.rs: -------------------------------------------------------------------------------- 1 | enum Color { 2 | Red, 3 | Green, 4 | Blue, 5 | RGB(i32, i32, i32) 6 | } 7 | 8 | enum Color2 { 9 | Red = 0xff0000, 10 | Green = 0x00ff00, 11 | Blue = 0x0000ff, 12 | } 13 | 14 | fn print_color(c: Color) { 15 | match c { 16 | Color::Red => println!("#ff0000"), 17 | Color::Green => println!("#00ff00"), 18 | Color::Blue => println!("#0000ff"), 19 | Color::RGB(r, g, b) => println!("#{:02x}{:02x}{:02x}", r, g, b) 20 | } 21 | } 22 | 23 | enum Day { // achterliggend discriminator vanaf 0 24 | Monday, 25 | Tuesday, 26 | Wednesday, 27 | Thursday, 28 | Friday, 29 | Saturday, 30 | Sunday, 31 | } 32 | 33 | 34 | impl Day { 35 | fn mood(&self) { 36 | println!("{}", match *self { 37 | Day::Friday => "it's friday!", 38 | Day::Saturday | Day::Sunday => "weekend :-)", 39 | _ => "weekday...", 40 | }) 41 | } 42 | } 43 | 44 | fn main() { 45 | print_color(Color::Red); 46 | print_color(Color::RGB(0x12, 0x45, 0xba)); 47 | 48 | // enums can be casted into integers 49 | println!("roses are #{:06x}", Color2::Red as i32); 50 | println!("violets are #{:06x}", Color2::Blue as i32); 51 | 52 | let today = Day::Monday; 53 | today.mood(); 54 | } 55 | // #ff0000 56 | // #1245ba 57 | // roses are #ff0000 58 | // violets are #0000ff 59 | // weekday... -------------------------------------------------------------------------------- /Chapter 4/code/input.rs: -------------------------------------------------------------------------------- 1 | use std::io; 2 | 3 | fn main() { 4 | println!("What's your name, noble warrior?"); 5 | let mut buf = String::new(); 6 | // version with .ok().expect(): 7 | // io::stdin().read_line(&mut buf) 8 | // .ok() 9 | // .expect("Failed to read line"); 10 | // let name = buf.trim(); 11 | // println!("{}, that's a mighty name indeed!", name); 12 | 13 | // version with unwrap(): 14 | // io::stdin().read_line(&mut buf).unwrap(); 15 | // let name = buf.trim(); 16 | // println!("{}, that's a mighty name indeed!", name); 17 | 18 | // alternative with testing is_ok(): 19 | if io::stdin().read_line(&mut buf).is_ok() { 20 | let name = buf.trim(); 21 | println!("{}, that's a mighty name indeed!", name); 22 | } 23 | else { 24 | println!("Failed to read line!"); 25 | } 26 | } 27 | // What's your name, noble warrior? 28 | // Riddick 29 | // Riddick, that's a mighty name indeed! 30 | 31 | -------------------------------------------------------------------------------- /Chapter 4/code/match_tuple.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | // let status = 7; 3 | // error: mismatched types: 4 | // expected `_`, found `(_, _)` (expected integral variable, found tuple) [E0308] 5 | 6 | // correction: 7 | // let status = ('a', false); 'a' is not an integer 8 | let status = (42, true); 9 | match status { 10 | (0, true) => println!("Success"), 11 | (_, true) => println!("Pyrrhic victory"), // Any first value matches 12 | (_, _) => println!("Complete loss") // Any pair of values will match 13 | } 14 | 15 | let x = (59, false); 16 | match x { 17 | (n, true) if (n >= 20 && n <= 26) => println!("true and between 20 and 26"), 18 | (20...26, true) => println!("true and between 20 and 26"), 19 | (n, true) if !(n >= 20 && n <= 26) => println!("true and not between 20 and 26"), 20 | (40...49, _) => println!("between 40 and 49"), 21 | (_, _) => println!("Everything else") 22 | } 23 | 24 | } 25 | // Pyrrhic victory 26 | // Everything else 27 | 28 | -------------------------------------------------------------------------------- /Chapter 4/code/pattern_match.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/code/pattern_match2.rs: -------------------------------------------------------------------------------- 1 | struct Point { 2 | x: i32, 3 | y: i32, 4 | } 5 | 6 | fn main() { 7 | // exhaustive match with _: 8 | let magician = "Gandalf"; 9 | match magician { 10 | "Gandalf" => println!("A good magician!"), 11 | "Sauron" => println!("A magician turned bad!"), 12 | _ => println!("No magician turned up!") 13 | } 14 | 15 | // matching several values in a branch: 16 | let magical_number: i32 = 42; 17 | match magical_number { 18 | // Match a single value 19 | 1 => println!("Unity!"), 20 | // Match several values 21 | 2 | 3 | 5 | 7 | 11 => println!("Ok, these are primes"), 22 | // Match an inclusive range 23 | // 40...42 => println!("It is contained in this range"), 24 | num @ 40...42 => println!("{} is contained in this range ", num), 25 | // Handle the rest of cases 26 | _ => println!("No magic at all!"), 27 | } 28 | 29 | // destructuring a tuple: 30 | // see match_tuple.rs 31 | 32 | // destructuring a struct: 33 | let origin = Point { x: 0, y: 0 }; 34 | match origin { 35 | Point { x: x, y: y } => println!("This is the point: ({},{})", x, y), 36 | } 37 | 38 | // destructuring values and using guards: 39 | let loki = ("Loki", true, 800u32); 40 | match loki { 41 | (name, demi, _) if demi => { 42 | print!("This is a demigod "); 43 | println!("called {}", name); 44 | } 45 | (name, _, _) if name == "Thor" => println!("This is Thor!"), 46 | (_, _, pow) if pow <= 1000 => println!("This is a powerless god"), 47 | _ => println!("This is something else") 48 | } 49 | 50 | // matching on a pointer: 51 | let x = &5; 52 | match x { 53 | &val => println!("Got a pointer value: {}", val), 54 | } 55 | 56 | } 57 | // A good magician! 58 | // 42 is contained in this range 59 | // This is the point: (0,0) 60 | // This is a demigod called Loki 61 | // Got a pointer value: 5 -------------------------------------------------------------------------------- /Chapter 4/code/remove_elem_vector.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let mut vec1: Vec = (0..10).collect(); 3 | vec1.retain(|&x| !is_odd(x)); 4 | println!("{:?}", vec1) 5 | } 6 | 7 | fn is_odd(n: i32) -> bool { n % 2 != 0 } 8 | // [0, 2, 4, 6, 8] -------------------------------------------------------------------------------- /Chapter 4/code/strings.rs: -------------------------------------------------------------------------------- 1 | use std::string; 2 | use std::str::FromStr; 3 | 4 | fn main() { 5 | // string slices of type &str 6 | let magician1 = "Merlin"; 7 | // let magician2: &'static str = "Gandalf"; 8 | let magician2: &str = "Gandalf"; 9 | let greeting = "Hello, 世界!"; 10 | println!("Magician {} greets magician {} with {}", 11 | magician1, magician2, greeting); 12 | 13 | // making a String 14 | let mut str1 = String::new(); // created empty, no allocation 15 | let mut str2 = String::with_capacity(25); // created with 25 bytes allocated 16 | 17 | // convert a string slice into a String 18 | let mut str3 = magician1.to_string(); 19 | println!("{}", str3); // Merlin 20 | 21 | // get a string slice from a String 22 | let sl1 = &str3; 23 | println!("{}", sl1); // Merlin 24 | 25 | // turning a String into a slice with &* 26 | let strm = "Sauron".to_string(); 27 | println!("{}", &*strm); 28 | 29 | // comparing Strings and string slices: 30 | if &str3[..] == magician1 { 31 | println!("We got the same magician alright!") 32 | } 33 | // shorter: 34 | if &str3 == magician1 { 35 | println!("We got the same magician alright!") 36 | } 37 | 38 | // building a String 39 | let c1 = 'Ɵ'; // character c1 40 | str1.push(c1); 41 | println!("{}", str1); // Ɵ 42 | str1.push_str(" Level 1 is finished - "); 43 | println!("{}", str1); // Ɵ Level 1 is finished - 44 | str1.push_str("Rise up to Level 2"); 45 | println!("{}", str1); // Ɵ Level 1 is finished - Rise up to Level 2 46 | 47 | // concatenating strings: 48 | let st1 = "United ".to_string(); // st1 is of type String 49 | let st2 = "States"; 50 | let country = st1 + st2; 51 | println!("The country is {}", country); 52 | let st3 = "United ".to_string(); 53 | let st4 = "States".to_string(); 54 | let country = st3 + &st4; 55 | println!("The country is {}", country); 56 | 57 | // iterate over String: 58 | // characters: 59 | for c in magician1.chars() { 60 | print!("{} - ", c); 61 | } // M - e - r - l - i - n - 62 | 63 | for c in magician1.bytes() { 64 | print!("{} - ", c); 65 | } // 77 - 101 - 114 - 108 - 105 - 110 66 | 67 | // taking a character via an index does not work: 68 | // error: the trait `core::ops::Index<_>` is not implemented for the type `str` [E0277] 69 | // println!("{}", magician1[1]); 70 | println!("{:?}", magician1.chars().nth(1)); // Some('e') 71 | 72 | // words: 73 | for word in str1.split(" ") { 74 | print!("{} / ", word); 75 | } 76 | println!(""); 77 | 78 | // changing a String: 79 | let str5 = str1.replace("Level", "Floor"); 80 | println!("{}", str5); // Ɵ Level 1 is finished - Rise up to Level 2 81 | 82 | // from_str: 83 | println!("{:?}", f64::from_str("3.6")); 84 | let number: f64 = f64::from_str("3.6").unwrap(); 85 | 86 | // string parameters: 87 | println!("Length of Merlin: {}", how_long(magician1)); 88 | println!("Length of str1: {}", how_long(&str1)); 89 | println!("Length of str1: {}", how_long(&str1[..])); 90 | 91 | // escape characters and raw strings r"" or r#""#: 92 | println!("{}", "Ru\nst"); 93 | println!("{}", r"Ru\nst"); 94 | println!("{}", r#"Ru\nst"#); 95 | } 96 | 97 | fn how_long(s: &str) -> usize { s.len() } 98 | 99 | // Magician Merlin greets magician Gandalf with Hello, 世界! 100 | // Merlin 101 | // Merlin 102 | // Sauron 103 | // We got the same magician alright! 104 | // We got the same magician alright! 105 | // Ɵ 106 | // Ɵ Level 1 is finished - 107 | // Ɵ Level 1 is finished - Rise up to Level 2 108 | // The country is United States 109 | // The country is United States 110 | // M - e - r - l - i - n - 77 - 101 - 114 - 108 - 105 - 110 - Some('e') 111 | // Ɵ / Level / 1 / is / finished / - / Rise / up / to / Level / 2 / 112 | // Ɵ Floor 1 is finished - Rise up to Floor 2 113 | // Ok(3.6) 114 | // Length of Merlin: 6 115 | // Length of str1: 43 116 | // Length of str1: 43 117 | // Ru 118 | // st 119 | // Ru\nst 120 | // Ru\nst -------------------------------------------------------------------------------- /Chapter 4/code/structs.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 1 {} is at level {}", pl1.nname, pl1.level); 25 | pl1.level = 3; 26 | 27 | // update syntax: 28 | let pl2 = Player{ nname: "Ivo", ..pl1 }; 29 | println!("Player 2 {} is at level {}", pl2.nname, pl2.level); 30 | 31 | // destructuring a struct: 32 | let Player{ health: ht, nname: nn, .. } = pl1; 33 | println!("Player {} has health {}", nn, ht); 34 | 35 | // pointers do automatic dereferencing when accessing data structure elements: 36 | let ps = &Player{ nname: "John", health: 95, level: 1 }; 37 | println!("{} == {}", ps.nname, (*ps).nname); 38 | } 39 | // Health 73 - Level 2 40 | // weight is 250 kilograms 41 | // Player 1 Dzenan is at level 2 42 | // Player 2 Ivo is at level 3 43 | // Player Dzenan has health 73 44 | // John == John -------------------------------------------------------------------------------- /Chapter 4/code/tuples.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 | let pair_thor = (thor.0, thor.2); 19 | let (god, strength) = increase_power2(pair_thor); 20 | println!("This god {} has now {} strength", god, strength); 21 | 22 | // swapping variables with a tuple: 23 | let mut n = 0; 24 | let mut m = 1; 25 | let (n, m) = (m, n); 26 | println!("n: {} m: {}", n, m); 27 | } 28 | 29 | fn increase_power(name: &str, power: u32) -> (&str, u32) { 30 | if power > 1000 { 31 | (name, power * 3) 32 | } else { 33 | (name, power * 2) 34 | } 35 | } 36 | 37 | fn increase_power2((name, power): (&str, u32)) -> (&str, u32) { 38 | if power > 1000 { 39 | (name, power * 3) 40 | } else { 41 | (name, power * 2) 42 | } 43 | } 44 | 45 | // ("Thor", true, 3500u) 46 | // Thor - true - 3500 47 | // Thor has 3500 points of power 48 | // This god Thor has now 10500 strength 49 | // This god Thor has now 10500 strength 50 | // n: 1 m: 0 -------------------------------------------------------------------------------- /Chapter 4/exercises/chars_string.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() { // same as as_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/match_type.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | // let status = 7; 3 | // error: mismatched types: 4 | // expected `_`, found `(_, _)` (expected integral variable, found tuple) [E0308] 5 | 6 | // correction: 7 | // let status = ('a', false); 'a' is not an integer 8 | let status = (42, true); 9 | match status { 10 | (0, true) => println!("Success"), 11 | (_, true) => println!("Pyrrhic victory"), // Any first value matches 12 | (_, _) => println!("Complete loss") // Any pair of values will match 13 | } 14 | } 15 | // Pyrrhic victory 16 | 17 | 18 | -------------------------------------------------------------------------------- /Chapter 4/exercises/matching.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let x = (59, false); 3 | 4 | match x { 5 | // (n, true) if (n >= 20 && n <= 26) => println!("true and between 20 and 26"), 6 | (20...26, true) => println!("true and between 20 and 26"), 7 | (n, true) if !(n >= 20 && n <= 26) => println!("true and not between 20 and 26"), 8 | (40...49, _) => println!("between 40 and 49"), 9 | (_, _) => println!("Everything else") 10 | } 11 | } -------------------------------------------------------------------------------- /Chapter 4/exercises/monster.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/pattern_match.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/tuples_ex.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/code/adapters_consumers.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/code/dispatch.rs: -------------------------------------------------------------------------------- 1 | struct Circle; 2 | struct Triangle; 3 | 4 | trait Figure { 5 | fn print(&self); 6 | } 7 | 8 | impl Figure for Circle { 9 | fn print(&self) { 10 | println!("Circle"); 11 | } 12 | } 13 | 14 | impl Figure for Triangle { 15 | fn print(&self) { 16 | println!("Triangle"); 17 | } 18 | } 19 | 20 | // static dispatch 21 | fn log(figure: &T) { 22 | figure.print(); 23 | } 24 | 25 | // dynamic dispatch: function takes a trait object 26 | fn logd(figure: &Figure) { 27 | figure.print(); 28 | } 29 | 30 | fn main() { 31 | // static dispatch 32 | let circle = Circle; 33 | let triangle = Triangle; 34 | 35 | log(&circle); 36 | log(&triangle); 37 | 38 | // dynamic dispatch: 39 | let mut figures: Vec> = Vec::new(); 40 | figures.push(Box::new(Circle)); 41 | figures.push(Box::new(Triangle)); 42 | 43 | // the precise type of figure can only be known at runtime: 44 | for figure in figures { 45 | // log(&*figure); // error: the trait `core::marker::Sized` is not implemented for the type `Figure` 46 | logd(&*figure); 47 | } 48 | } 49 | // Circle 50 | // Triangle 51 | // Circle 52 | // Triangle -------------------------------------------------------------------------------- /Chapter 5/code/errors.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | // panics: 3 | let x = 3; 4 | // let y = 0; 5 | let y = 3; 6 | // x / y; // thread '
' panicked at 'attempted to divide by zero' 7 | // if y == 0 { panic!("Division by 0 occurred, exiting"); } 8 | println!("{}", div(x, y)); // returns 1 if y = 3 9 | 10 | // assert!(x == 5); // thread '
' panicked at 'assertion failed: x == 5' 11 | // assert_eq!(x, 5); // thread '
' panicked at 'assertion failed: (left: `3`, right: `5`)', 12 | // unreachable!(); // thread '
' panicked at 'internal error: entered unreachable code' 13 | } 14 | 15 | fn div(x: i32, y: i32) -> f32 { 16 | // if y == 0 { panic!("Division by 0 occurred, exiting"); } 17 | assert!(y != 0, "Division by 0 occurred, exiting"); 18 | (x / y) as f32 19 | } -------------------------------------------------------------------------------- /Chapter 5/code/generics.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 | 38 | // match m { 39 | // Ok(sq) => println!("The square root of 42 is {}", sq), 40 | // Err(str) => println!("{}", str) 41 | // } 42 | 43 | let res = match m { 44 | Ok(sq) => sq, 45 | Err(_) => -1.0 46 | }; 47 | println!("res is {}", res); 48 | } 49 | 50 | fn sqroot(r: f32) -> Result { 51 | // if r < 0.0 { 52 | // return Err("Number cannot be negative!".to_string()); 53 | // } 54 | assert!(r >= 0.0, "Number cannot be negative!"); 55 | Ok(f32::sqrt(r)) 56 | } 57 | 58 | fn second(pair: Pair) { 59 | pair.second; 60 | } 61 | // The square root of 42 is 6.480741 62 | // mres is 6.480741 63 | // for m == -5.0: Number cannot be negative! -------------------------------------------------------------------------------- /Chapter 5/code/higher_functions.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let mut strength = 26; 3 | println!("My tripled strength equals {}", triples(strength) ); // 78 4 | println!("My strength is still {}", strength); // 26 5 | strength = triples(strength); 6 | println!("My strength is now {}", strength); // 78 7 | 8 | // function taking another function as parameter: 9 | strength = again(triples, strength); 10 | println!("I got so lucky to turn my strength into {}", strength); // 702 (= 3 * 3 * 78) 11 | 12 | // closures instead of a named function: 13 | strength = 78; 14 | let triples = |n| { 3 * n }; // a closure 15 | // closures infer the types of their arguments and return value types 16 | strength = again(triples, strength); 17 | println!("My strength is now {}", strength); // 702 18 | 19 | // inlining: 20 | strength = 78; 21 | strength = again(|n| {3 * n} , strength); // an inline closure 22 | // simplified without { }: 23 | // strength = again(|n| 3 * n , strength); // an inline closure 24 | println!("My strength is now {}", strength); // 702 25 | 26 | // a closure has access to (captures) the variables in its scope: 27 | let x: i32 = 42; 28 | let print_add = |s| { 29 | println!("x is {}", x); 30 | x + s 31 | }; 32 | // || {...} is a closure which takes no arguments 33 | // each closure has its own unique type 34 | let res = print_add(strength); // <- here the closure is called "x is 42" 35 | assert_eq!(res, 744); // 42 + 702 36 | 37 | // a moving closure: 38 | let m: i32 = 42; 39 | let print_add_move = move |s| { 40 | println!("m is {}", m); 41 | m + s 42 | }; 43 | let res = print_add_move(strength); 44 | assert_eq!(res, 744); // 42 + 702 45 | } 46 | 47 | fn triples(s: i32) -> i32 { 48 | 3 * s 49 | } 50 | 51 | // this function does exactly the same as function triples: 52 | fn triplesref(s: &i32) -> i32 { 53 | 3 * *s 54 | } 55 | 56 | fn again i32>(f: F, s: i32) -> i32 { 57 | f(f(s)) 58 | } 59 | // Output: 60 | // My tripled strength equals 78 61 | // My strength is still 26 62 | // My strength is now 78 63 | // I got so lucky to turn my strength into 702 64 | // My strength is now 702 65 | // My strength is now 702 66 | // x is 42 67 | // m is 42 -------------------------------------------------------------------------------- /Chapter 5/code/impl_add.rs: -------------------------------------------------------------------------------- 1 | use std::ops::Add; 2 | 3 | #[derive(Debug)] 4 | struct AType { 5 | value: i32, 6 | } 7 | 8 | impl AType { 9 | fn new(value: i32) -> AType { 10 | AType { value: value } 11 | } 12 | } 13 | 14 | impl Add for AType { 15 | type Output = AType; 16 | 17 | fn add(self, other: AType) -> AType { 18 | AType { value: self.value + other.value } 19 | } 20 | } 21 | 22 | 23 | fn main() { 24 | let at1 = AType{ value: 7 }; 25 | let at2 = AType{ value: 42 }; 26 | let at3 = at1.add(at2); 27 | println!("{:?}", at3); 28 | } 29 | // AType { value: 49 } 30 | -------------------------------------------------------------------------------- /Chapter 5/code/input_number.rs: -------------------------------------------------------------------------------- 1 | use std::io; 2 | 3 | fn main() { 4 | println!("Give an integer number bigger than 0:"); 5 | let mut buf = String::new(); 6 | io::stdin().read_line(&mut buf) 7 | .ok() 8 | .expect("Failed to read line"); 9 | let input_num: Result = buf.trim().parse(); 10 | let res = match input_num { 11 | Ok(num) => num, 12 | Err(_) => 0 13 | }; 14 | println!("{}, that's a beautiful number", res); 15 | } -------------------------------------------------------------------------------- /Chapter 5/code/input_number2.rs: -------------------------------------------------------------------------------- 1 | use std::io; 2 | 3 | fn main() { 4 | println!("Give an integer number bigger than 0:"); 5 | let num = read_u32(); 6 | match num { 7 | Some(val) => println!("That's the number: {}", val), 8 | None => println!("Failed to read number.") 9 | } 10 | } 11 | 12 | fn read_u32() -> Option { 13 | let mut buf = String::new(); 14 | if io::stdin().read_line(&mut buf).is_ok() { 15 | let result = buf.trim().parse::(); 16 | return match result { 17 | Ok(value) => Some(value), 18 | Err(_) => None //Failed to parse 19 | }; 20 | } 21 | //Failed to read from stream 22 | None 23 | } 24 | 25 | -------------------------------------------------------------------------------- /Chapter 5/code/iterators.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/code/method_enum.rs: -------------------------------------------------------------------------------- 1 | enum Day { // achterliggend discriminator vanaf 0 2 | Monday, 3 | Tuesday, 4 | Wednesday, 5 | Thursday, 6 | Friday, 7 | Saturday, 8 | Sunday, 9 | } 10 | 11 | impl Day { 12 | fn mood(&self) { 13 | println!("{}", match *self { 14 | Day::Friday => "it's friday!", 15 | Day::Saturday | Day::Sunday => "weekend :-)", 16 | _ => "weekday...", 17 | }) 18 | } 19 | } 20 | 21 | fn main() { 22 | let today = Day::Tuesday; 23 | today.mood(); 24 | } 25 | // weekday... 26 | -------------------------------------------------------------------------------- /Chapter 5/code/methods.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/code/sqrt_match.rs: -------------------------------------------------------------------------------- 1 | use std::f32; 2 | 3 | fn main() { 4 | // using Result 5 | let m = sqroot(42.0); 6 | // let m = sqroot(-5.0); 7 | 8 | // match m { 9 | // Ok(sq) => println!("The square root of 42 is {}", sq), 10 | // Err(str) => println!("{}", str) 11 | // } 12 | 13 | let res = match m { 14 | Ok(sq) => sq, 15 | Err(_) => -1.0 16 | }; 17 | println!("res is {}", res); 18 | } 19 | 20 | fn sqroot(r: f32) -> Result { 21 | // if r < 0.0 { 22 | // return Err("Number cannot be negative!".to_string()); 23 | // } 24 | assert!(r >= 0.0, "Number cannot be negative!"); 25 | Ok(f32::sqrt(r)) 26 | } 27 | // The square root of 42 is 6.480741 28 | // mres is 6.480741 29 | // for m == -5.0: Number cannot be negative! 30 | // res is 6.4807405 -------------------------------------------------------------------------------- /Chapter 5/code/super_traits.rs: -------------------------------------------------------------------------------- 1 | #[derive(Debug)] 2 | struct Zombie { health: u32, damage: u32 } 3 | 4 | trait SuperMonster { 5 | fn test(); 6 | } 7 | 8 | // this 'inheritance' implies that any type that implements trait Monster 9 | // must also implement the trait SuperMonster 10 | trait Monster : SuperMonster { 11 | fn new(hlt: u32, dam: u32) -> Self; 12 | 13 | fn attack(&self); 14 | fn noise(&self) -> &'static str; 15 | 16 | fn attacks_with_sound(&self) { 17 | println!("The Monster attacks by making an awkward sound {}", self.noise()); 18 | } 19 | } 20 | 21 | impl SuperMonster for Zombie { 22 | fn test() { 23 | println!("I am a SuperMonster"); 24 | } 25 | } 26 | 27 | impl Monster for Zombie { 28 | fn new(mut h: u32, d: u32) -> Zombie { 29 | // constraints: 30 | if h > 100 { h = 100; } 31 | Zombie { health: h, damage: d } 32 | } 33 | 34 | fn attack(&self) { 35 | println!("The Zombie bites! Your health lowers with {} damage points.", 2 * self.damage); 36 | } 37 | 38 | fn noise(&self) -> &'static str { 39 | "Aaargh!" 40 | } 41 | } 42 | 43 | fn main() { 44 | // use Monster; // <- not necessary! 45 | let zmb1 = Zombie { health: 75, damage: 15 }; 46 | println!("Oh no, I hear: {}", zmb1.noise()); 47 | zmb1.attack(); 48 | println!("{:?}", zmb1); 49 | } 50 | // Oh no, I hear: Aaargh! 51 | // The Zombie bites! Your health lowers with 30 damage points. 52 | // Zombie { health: 75, damage: 15 } -------------------------------------------------------------------------------- /Chapter 5/code/trait_constraints/Cargo.lock: -------------------------------------------------------------------------------- 1 | [root] 2 | name = "trait_constraints" 3 | version = "0.0.1" 4 | dependencies = [ 5 | "num 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", 6 | ] 7 | 8 | [[package]] 9 | name = "libc" 10 | version = "0.1.7" 11 | source = "registry+https://github.com/rust-lang/crates.io-index" 12 | 13 | [[package]] 14 | name = "num" 15 | version = "0.1.24" 16 | source = "registry+https://github.com/rust-lang/crates.io-index" 17 | dependencies = [ 18 | "rand 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 19 | "rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", 20 | ] 21 | 22 | [[package]] 23 | name = "rand" 24 | version = "0.3.8" 25 | source = "registry+https://github.com/rust-lang/crates.io-index" 26 | dependencies = [ 27 | "libc 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", 28 | ] 29 | 30 | [[package]] 31 | name = "rustc-serialize" 32 | version = "0.3.14" 33 | source = "registry+https://github.com/rust-lang/crates.io-index" 34 | 35 | -------------------------------------------------------------------------------- /Chapter 5/code/trait_constraints/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "trait_constraints" 3 | version = "0.0.1" 4 | authors = ["Ivo Balbaert "] 5 | 6 | [[bin]] 7 | name = "trait_constraints" 8 | 9 | [dependencies] 10 | num = "*" -------------------------------------------------------------------------------- /Chapter 5/code/trait_constraints/src/trait_constraints.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/code/trait_constraints/target/debug/.fingerprint/libc-674726c388d62fa2/dep-lib-libc: -------------------------------------------------------------------------------- 1 | F:\Rust\Rust book\Chapter 5 - Generalizing code with higher order functions and parametrization\code\trait_constraintsF:\Rust\Rust book\Chapter 5 - Generalizing code with higher order functions and parametrization\code\trait_constraints\target\debug\deps\liblibc-674726c388d62fa2.rlib: C:\Users\CVO\.cargo\registry\src\github.com-1ecc6299db9ec823\libc-0.1.7\rust/src/liblibc/lib.rs 2 | 3 | F:\Rust\Rust book\Chapter 5 - Generalizing code with higher order functions and parametrization\code\trait_constraints\target\debug\deps\libc-674726c388d62fa2.d: C:\Users\CVO\.cargo\registry\src\github.com-1ecc6299db9ec823\libc-0.1.7\rust/src/liblibc/lib.rs 4 | 5 | -------------------------------------------------------------------------------- /Chapter 5/code/trait_constraints/target/debug/.fingerprint/libc-674726c388d62fa2/lib-libc: -------------------------------------------------------------------------------- 1 | e5ae1bc9a10ac220 -------------------------------------------------------------------------------- /Chapter 5/code/trait_constraints/target/debug/.fingerprint/num-b6664aad0573bf89/dep-lib-num: -------------------------------------------------------------------------------- 1 | F:\Rust\Rust book\Chapter 5 - Generalizing code with higher order functions and parametrization\code\trait_constraintsF:\Rust\Rust book\Chapter 5 - Generalizing code with higher order functions and parametrization\code\trait_constraints\target\debug\deps\libnum-b6664aad0573bf89.rlib: C:\Users\CVO\.cargo\registry\src\github.com-1ecc6299db9ec823\num-0.1.24\src\lib.rs C:\Users\CVO\.cargo\registry\src\github.com-1ecc6299db9ec823\num-0.1.24\src\bigint.rs C:\Users\CVO\.cargo\registry\src\github.com-1ecc6299db9ec823\num-0.1.24\src\complex.rs C:\Users\CVO\.cargo\registry\src\github.com-1ecc6299db9ec823\num-0.1.24\src\integer.rs C:\Users\CVO\.cargo\registry\src\github.com-1ecc6299db9ec823\num-0.1.24\src\iter.rs C:\Users\CVO\.cargo\registry\src\github.com-1ecc6299db9ec823\num-0.1.24\src\traits.rs C:\Users\CVO\.cargo\registry\src\github.com-1ecc6299db9ec823\num-0.1.24\src\rational.rs 2 | 3 | F:\Rust\Rust book\Chapter 5 - Generalizing code with higher order functions and parametrization\code\trait_constraints\target\debug\deps\num-b6664aad0573bf89.d: C:\Users\CVO\.cargo\registry\src\github.com-1ecc6299db9ec823\num-0.1.24\src\lib.rs C:\Users\CVO\.cargo\registry\src\github.com-1ecc6299db9ec823\num-0.1.24\src\bigint.rs C:\Users\CVO\.cargo\registry\src\github.com-1ecc6299db9ec823\num-0.1.24\src\complex.rs C:\Users\CVO\.cargo\registry\src\github.com-1ecc6299db9ec823\num-0.1.24\src\integer.rs C:\Users\CVO\.cargo\registry\src\github.com-1ecc6299db9ec823\num-0.1.24\src\iter.rs C:\Users\CVO\.cargo\registry\src\github.com-1ecc6299db9ec823\num-0.1.24\src\traits.rs C:\Users\CVO\.cargo\registry\src\github.com-1ecc6299db9ec823\num-0.1.24\src\rational.rs 4 | 5 | -------------------------------------------------------------------------------- /Chapter 5/code/trait_constraints/target/debug/.fingerprint/num-b6664aad0573bf89/lib-num: -------------------------------------------------------------------------------- 1 | d0b118e895a08a00 -------------------------------------------------------------------------------- /Chapter 5/code/trait_constraints/target/debug/.fingerprint/rand-b924d9fc5b3eb5b8/dep-lib-rand: -------------------------------------------------------------------------------- 1 | F:\Rust\Rust book\Chapter 5 - Generalizing code with higher order functions and parametrization\code\trait_constraintsF:\Rust\Rust book\Chapter 5 - Generalizing code with higher order functions and parametrization\code\trait_constraints\target\debug\deps\librand-b924d9fc5b3eb5b8.rlib: C:\Users\CVO\.cargo\registry\src\github.com-1ecc6299db9ec823\rand-0.3.8\src\lib.rs C:\Users\CVO\.cargo\registry\src\github.com-1ecc6299db9ec823\rand-0.3.8\src\distributions/mod.rs C:\Users\CVO\.cargo\registry\src\github.com-1ecc6299db9ec823\rand-0.3.8\src\distributions\range.rs C:\Users\CVO\.cargo\registry\src\github.com-1ecc6299db9ec823\rand-0.3.8\src\distributions\gamma.rs C:\Users\CVO\.cargo\registry\src\github.com-1ecc6299db9ec823\rand-0.3.8\src\distributions\normal.rs C:\Users\CVO\.cargo\registry\src\github.com-1ecc6299db9ec823\rand-0.3.8\src\distributions\exponential.rs C:\Users\CVO\.cargo\registry\src\github.com-1ecc6299db9ec823\rand-0.3.8\src\distributions\ziggurat_tables.rs C:\Users\CVO\.cargo\registry\src\github.com-1ecc6299db9ec823\rand-0.3.8\src\isaac.rs C:\Users\CVO\.cargo\registry\src\github.com-1ecc6299db9ec823\rand-0.3.8\src\chacha.rs C:\Users\CVO\.cargo\registry\src\github.com-1ecc6299db9ec823\rand-0.3.8\src\reseeding.rs C:\Users\CVO\.cargo\registry\src\github.com-1ecc6299db9ec823\rand-0.3.8\src\rand_impls.rs C:\Users\CVO\.cargo\registry\src\github.com-1ecc6299db9ec823\rand-0.3.8\src\os.rs C:\Users\CVO\.cargo\registry\src\github.com-1ecc6299db9ec823\rand-0.3.8\src\read.rs 2 | 3 | F:\Rust\Rust book\Chapter 5 - Generalizing code with higher order functions and parametrization\code\trait_constraints\target\debug\deps\rand-b924d9fc5b3eb5b8.d: C:\Users\CVO\.cargo\registry\src\github.com-1ecc6299db9ec823\rand-0.3.8\src\lib.rs C:\Users\CVO\.cargo\registry\src\github.com-1ecc6299db9ec823\rand-0.3.8\src\distributions/mod.rs C:\Users\CVO\.cargo\registry\src\github.com-1ecc6299db9ec823\rand-0.3.8\src\distributions\range.rs C:\Users\CVO\.cargo\registry\src\github.com-1ecc6299db9ec823\rand-0.3.8\src\distributions\gamma.rs C:\Users\CVO\.cargo\registry\src\github.com-1ecc6299db9ec823\rand-0.3.8\src\distributions\normal.rs C:\Users\CVO\.cargo\registry\src\github.com-1ecc6299db9ec823\rand-0.3.8\src\distributions\exponential.rs C:\Users\CVO\.cargo\registry\src\github.com-1ecc6299db9ec823\rand-0.3.8\src\distributions\ziggurat_tables.rs C:\Users\CVO\.cargo\registry\src\github.com-1ecc6299db9ec823\rand-0.3.8\src\isaac.rs C:\Users\CVO\.cargo\registry\src\github.com-1ecc6299db9ec823\rand-0.3.8\src\chacha.rs C:\Users\CVO\.cargo\registry\src\github.com-1ecc6299db9ec823\rand-0.3.8\src\reseeding.rs C:\Users\CVO\.cargo\registry\src\github.com-1ecc6299db9ec823\rand-0.3.8\src\rand_impls.rs C:\Users\CVO\.cargo\registry\src\github.com-1ecc6299db9ec823\rand-0.3.8\src\os.rs C:\Users\CVO\.cargo\registry\src\github.com-1ecc6299db9ec823\rand-0.3.8\src\read.rs 4 | 5 | -------------------------------------------------------------------------------- /Chapter 5/code/trait_constraints/target/debug/.fingerprint/rand-b924d9fc5b3eb5b8/lib-rand: -------------------------------------------------------------------------------- 1 | cdc24bf0a6c7fbe1 -------------------------------------------------------------------------------- /Chapter 5/code/trait_constraints/target/debug/.fingerprint/rustc-serialize-9ef26f158d5284e0/dep-lib-rustc-serialize: -------------------------------------------------------------------------------- 1 | F:\Rust\Rust book\Chapter 5 - Generalizing code with higher order functions and parametrization\code\trait_constraintsF:\Rust\Rust book\Chapter 5 - Generalizing code with higher order functions and parametrization\code\trait_constraints\target\debug\deps\librustc_serialize-9ef26f158d5284e0.rlib: C:\Users\CVO\.cargo\registry\src\github.com-1ecc6299db9ec823\rustc-serialize-0.3.14\src\lib.rs C:\Users\CVO\.cargo\registry\src\github.com-1ecc6299db9ec823\rustc-serialize-0.3.14\src\serialize.rs C:\Users\CVO\.cargo\registry\src\github.com-1ecc6299db9ec823\rustc-serialize-0.3.14\src\collection_impls.rs C:\Users\CVO\.cargo\registry\src\github.com-1ecc6299db9ec823\rustc-serialize-0.3.14\src\base64.rs C:\Users\CVO\.cargo\registry\src\github.com-1ecc6299db9ec823\rustc-serialize-0.3.14\src\hex.rs C:\Users\CVO\.cargo\registry\src\github.com-1ecc6299db9ec823\rustc-serialize-0.3.14\src\json.rs 2 | 3 | F:\Rust\Rust book\Chapter 5 - Generalizing code with higher order functions and parametrization\code\trait_constraints\target\debug\deps\rustc_serialize-9ef26f158d5284e0.d: C:\Users\CVO\.cargo\registry\src\github.com-1ecc6299db9ec823\rustc-serialize-0.3.14\src\lib.rs C:\Users\CVO\.cargo\registry\src\github.com-1ecc6299db9ec823\rustc-serialize-0.3.14\src\serialize.rs C:\Users\CVO\.cargo\registry\src\github.com-1ecc6299db9ec823\rustc-serialize-0.3.14\src\collection_impls.rs C:\Users\CVO\.cargo\registry\src\github.com-1ecc6299db9ec823\rustc-serialize-0.3.14\src\base64.rs C:\Users\CVO\.cargo\registry\src\github.com-1ecc6299db9ec823\rustc-serialize-0.3.14\src\hex.rs C:\Users\CVO\.cargo\registry\src\github.com-1ecc6299db9ec823\rustc-serialize-0.3.14\src\json.rs 4 | 5 | -------------------------------------------------------------------------------- /Chapter 5/code/trait_constraints/target/debug/.fingerprint/rustc-serialize-9ef26f158d5284e0/lib-rustc-serialize: -------------------------------------------------------------------------------- 1 | fc83e55197717c3e -------------------------------------------------------------------------------- /Chapter 5/code/trait_constraints/target/debug/.fingerprint/trait_constraints-43ecad8ba4135d3d/bin-trait_constraints: -------------------------------------------------------------------------------- 1 | 26f8496635115a91 -------------------------------------------------------------------------------- /Chapter 5/code/trait_constraints/target/debug/.fingerprint/trait_constraints-43ecad8ba4135d3d/dep-bin-trait_constraints: -------------------------------------------------------------------------------- 1 | F:\Rust\Rust book\Chapter 5 - Generalizing code with higher order functions and parametrization\code\trait_constraintsF:\Rust\Rust book\Chapter 5 - Generalizing code with higher order functions and parametrization\code\trait_constraints\target\debug\trait_constraints.exe: src\trait_constraints.rs 2 | 3 | F:\Rust\Rust book\Chapter 5 - Generalizing code with higher order functions and parametrization\code\trait_constraints\target\debug\trait_constraints.d: src\trait_constraints.rs 4 | 5 | -------------------------------------------------------------------------------- /Chapter 5/code/trait_constraints/target/debug/deps/liblibc-674726c388d62fa2.rlib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ivo-Balbaert/start_rust/58531d58b4950420b345f04c4e2d4e5aeb164c0e/Chapter 5/code/trait_constraints/target/debug/deps/liblibc-674726c388d62fa2.rlib -------------------------------------------------------------------------------- /Chapter 5/code/trait_constraints/target/debug/deps/libnum-b6664aad0573bf89.rlib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ivo-Balbaert/start_rust/58531d58b4950420b345f04c4e2d4e5aeb164c0e/Chapter 5/code/trait_constraints/target/debug/deps/libnum-b6664aad0573bf89.rlib -------------------------------------------------------------------------------- /Chapter 5/code/trait_constraints/target/debug/deps/librand-b924d9fc5b3eb5b8.rlib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ivo-Balbaert/start_rust/58531d58b4950420b345f04c4e2d4e5aeb164c0e/Chapter 5/code/trait_constraints/target/debug/deps/librand-b924d9fc5b3eb5b8.rlib -------------------------------------------------------------------------------- /Chapter 5/code/trait_constraints/target/debug/deps/librustc_serialize-9ef26f158d5284e0.rlib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ivo-Balbaert/start_rust/58531d58b4950420b345f04c4e2d4e5aeb164c0e/Chapter 5/code/trait_constraints/target/debug/deps/librustc_serialize-9ef26f158d5284e0.rlib -------------------------------------------------------------------------------- /Chapter 5/code/trait_constraints/target/debug/trait_constraints.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ivo-Balbaert/start_rust/58531d58b4950420b345f04c4e2d4e5aeb164c0e/Chapter 5/code/trait_constraints/target/debug/trait_constraints.exe -------------------------------------------------------------------------------- /Chapter 5/code/traits.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/code/try_input_number.rs: -------------------------------------------------------------------------------- 1 | use std::io; 2 | use std::error; 3 | 4 | fn main() { 5 | print!("Give a positive secret number: "); 6 | match input_num() { 7 | Ok(v) => println!("Input value is: {}", v), 8 | Err(e) => println!("Error - Please input an integer number!: {}", e) 9 | } 10 | } 11 | 12 | fn input_num() -> Result> { 13 | let mut input = String::new(); 14 | try!(io::stdin().read_line(&mut input)); 15 | Ok(try!(input.trim().parse())) 16 | } -------------------------------------------------------------------------------- /Chapter 5/code/write.rs: -------------------------------------------------------------------------------- 1 | use std::io::Write; // in order to be able to use write! on a vector 2 | 3 | fn main() { 4 | let mut vec1 = Vec::new(); 5 | write!(&mut vec1, "test"); 6 | println!("{:?}", vec1); 7 | } 8 | // [116, 101, 115, 116] 9 | -------------------------------------------------------------------------------- /Chapter 5/exercises/complex.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/draw_trait.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.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/range_next.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/code/boxes1.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/code/boxes2.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 | // automatic dereferencing: 25 | let ua = Box::new([1, 2, 3]); 26 | println!("{}", ua[0]); // 1 27 | 28 | } 29 | 30 | fn use_alien(a: Box) { 31 | println!("An alien from planet {} is freed", a.planet); 32 | } 33 | 34 | fn use_alien2(a: &Alien) { 35 | println!("An alien from planet {} is freed", a.planet); 36 | } 37 | 38 | struct Recurs { 39 | list: Vec, 40 | rec_list: Option> 41 | } 42 | 43 | // 67 44 | // 4 45 | // An alien from planet Mars is freed 46 | // 1 -------------------------------------------------------------------------------- /Chapter 6/code/boxes_experimental.rs: -------------------------------------------------------------------------------- 1 | // #![feature(box_patterns)] 2 | 3 | struct Alien { 4 | planet: String, 5 | n_tentacles: u32, 6 | } 7 | 8 | fn main() { 9 | // error: box expression syntax is experimental; you can call `Box::new` instead. 10 | // let a = box 5i32; 11 | // mutable reference to a boxed value: 12 | // let mut a0 = box Alien{ planet: "Mars".to_string(), no_tentacles: 4 }; 13 | // println!("{}", a0.no_tentacles); // 4 14 | 15 | // The value can be extracted by the de-structuring pattern: let box m = a; 16 | // a mechanism which is also called unboxing a into m. 17 | // extract the value: 18 | // let box m = a; 19 | // println!("{}", m); 20 | 21 | } 22 | -------------------------------------------------------------------------------- /Chapter 6/code/clone.rs: -------------------------------------------------------------------------------- 1 | struct Block { 2 | number: Box 3 | } 4 | 5 | impl Clone for Block { 6 | fn clone(&self) -> Self { 7 | Block{ number: self.number.clone() } 8 | } 9 | } 10 | 11 | fn print_block(block: Block) { 12 | println!("{:p}: {:?}", block.number, block.number); 13 | } 14 | 15 | fn main() { 16 | let block = Block{ number: Box::new(1) }; 17 | println!("{:p}: {:?}", block.number, block.number); 18 | 19 | print_block(block.clone()); 20 | } 21 | // 0x2424008: 1 22 | // 0x2424028: 1 -------------------------------------------------------------------------------- /Chapter 6/code/drop.rs: -------------------------------------------------------------------------------- 1 | struct Block { 2 | number: i32 3 | } 4 | 5 | impl Drop for Block { 6 | fn drop(&mut self) { 7 | println!("Dropping!"); 8 | } 9 | } 10 | 11 | fn print_block(block: Block) { 12 | println!("In function print_block"); 13 | } 14 | 15 | fn main() { 16 | let block = Block{ number: 1 }; 17 | // move of value block: 18 | print_block(block); 19 | println!("Back in main!"); 20 | } 21 | // In function print_block 22 | // Dropping! 23 | // Back in main! -------------------------------------------------------------------------------- /Chapter 6/code/errors.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/code/lifetimes.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 | struct MagicNumber2 { 26 | value: u64 27 | } 28 | 29 | fn main() { 30 | // lifetimes restricted to a function: 31 | let n = 42u32; 32 | // copy behaviour: 33 | // no move, only a copy of the value from n to n2: 34 | let n2 = n; 35 | println!("The value of n2 is {}, the same as n", n2); 36 | 37 | life(n); 38 | // println!("{}", m); // error: unresolved name `m`. 39 | // println!("{}", o); // error: unresolved name `o`. 40 | 41 | // lifetime restricted to a code block: 42 | { 43 | let phi = 1.618; 44 | } 45 | // error: unresolved name `phi`. 46 | // println!("The value of phi is {}", phi); 47 | 48 | // let m = return_magician(); 49 | // println!("{} has {}", m.name, m.power); 50 | 51 | // copies because MagicNumber implements the Copy or Clone trait 52 | let mag = MagicNumber { value: 42 }; 53 | let mag2 = mag; 54 | let mag3 = mag.clone(); 55 | println!("{:?}", mag); 56 | println!("{:?}", mag2); 57 | // mag, mag2 and mag3 are 3 different objects: their addresses are different: 58 | println!("{:p}", &mag); // address is 0x23fb38 59 | println!("{:p}", &mag2); // address is 0x23fa80 60 | println!("{:p}", &mag3); // address is 0x23fb28 61 | // *const is a so called raw pointer, see Chapter 9 62 | println!("{:?}", &mag as *const MagicNumber); // address is 0x23fb38 63 | println!("{:?}", &mag2 as *const MagicNumber); // address is 0x23fb30 64 | println!("{:?}", &mag3 as *const MagicNumber); // address is 0x23fb28 65 | 66 | // move of struct value: 67 | let mag = MagicNumber2 { value: 108 }; 68 | println!("{:p}", &mag); // address is 0x23f6e8 69 | let mag2 = mag; 70 | // println!("{:p}", &mag); // error: use of moved value 'mag' 71 | println!("{:p}", &mag2); // address is 0x23f658 72 | } 73 | 74 | fn life(m: u32) -> u32 { 75 | let o = m; 76 | o 77 | } 78 | 79 | fn transform<'a>(s: &'a str) { /* ... */ } 80 | fn transform_without_lifetime(s: &str) { /* ... */ } 81 | 82 | // fn return_magician<'a>() -> &'a Magician { 83 | // let mag = Magician { name: "Gandalf", power: 4625 }; 84 | // &mag // error: `mag` does not live long enough 85 | // } 86 | 87 | // The value of n2 is 42, the same as n 88 | // MagicNumber { value: 42 } 89 | // MagicNumber { value: 42 } 90 | // 0x23fb38 91 | // 0x23fb30 92 | // 0x23fb28 -------------------------------------------------------------------------------- /Chapter 6/code/linked_list.rs: -------------------------------------------------------------------------------- 1 | // Allow Cons and Nil to be referred to without namespacing 2 | use List::{Cons, Nil}; 3 | 4 | // A linked list node, which can take on any of these two variants 5 | enum List { 6 | // Cons: Tuple struct that wraps an element and a pointer to the next node 7 | Cons(u32, Box), 8 | // Nil: A node that signifies the end of the linked list 9 | Nil, 10 | } 11 | 12 | // generic List: 13 | enum GList { 14 | Cons(T, Box>), 15 | Nil, 16 | } 17 | 18 | // Methods can be attached to an enum 19 | impl List { 20 | // Create an empty list 21 | fn new() -> List { 22 | // `Nil` has type `List` 23 | Nil 24 | } 25 | 26 | // Consume a list, and return the same list with a new element at its front 27 | fn prepend(self, elem: u32) -> List { 28 | // `Cons` also has type List 29 | Cons(elem, Box::new(self)) 30 | } 31 | 32 | // Return the length of the list 33 | fn len(&self) -> u32 { 34 | // `self` has to be matched, because the behavior of this method 35 | // depends on the variant of `self` 36 | // `self` has type `&List`, and `*self` has type `List`, matching on a 37 | // concrete type `T` is preferred over a match on a reference `&T` 38 | match *self { 39 | // Can't take ownership of the tail, because `self` is borrowed; 40 | // instead take a reference to the tail 41 | Cons(_, ref tail) => 1 + tail.len(), 42 | // Base Case: An empty list has zero length 43 | Nil => 0 44 | } 45 | } 46 | 47 | // Return representation of the list as a (heap allocated) string 48 | fn stringify(&self) -> String { 49 | match *self { 50 | Cons(head, ref tail) => { 51 | // `format!` is similar to `print!`, but returns a heap 52 | // allocated string instead of printing to the console 53 | format!("{}, {}", head, tail.stringify()) 54 | }, 55 | Nil => { 56 | format!("Nil") 57 | }, 58 | } 59 | } 60 | } 61 | 62 | fn main() { 63 | // Create an empty linked list 64 | let mut list = List::new(); 65 | 66 | // Append some elements 67 | list = list.prepend(1); 68 | list = list.prepend(2); 69 | list = list.prepend(3); 70 | 71 | // Show the final state of the list 72 | println!("linked list has length: {}", list.len()); 73 | println!("{}", list.stringify()); 74 | } 75 | // linked list has length: 3 76 | // 3, 2, 1, Nil -------------------------------------------------------------------------------- /Chapter 6/code/moving_closure.rs: -------------------------------------------------------------------------------- 1 | struct Block { 2 | number: i32 3 | } 4 | 5 | fn main() { 6 | let block = Block{ number:1 }; 7 | // ordinary closure: 8 | let closure = || { println!("n: {:?}", block.number); }; 9 | closure(); 10 | println!("n: {:?}", block.number); 11 | 12 | let block = Block{ number:1 }; 13 | // moving closure: 14 | // closure takes ownership of the block value 15 | let closure = move || {println!("n: {:?}", block.number); }; 16 | closure(); 17 | // error: use of moved value: `block.number` 18 | // println!("n: {:?}", block.number); 19 | } 20 | // n: 1 21 | // n: 1 22 | // n: 1 -------------------------------------------------------------------------------- /Chapter 6/code/ownership1.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 | // let kl2 = transform(klaatu); 12 | // let klaatu = transform(klaatu); 13 | // println!("{}", klaatu.planet); // use of moved value 'klaatu.planet' 14 | 15 | // a borrowing of the resource: 16 | // let kl2 = &klaatu; // a borrowing or reference 17 | let kl2 = &mut klaatu; // a mutable reference 18 | kl2.n_tentacles = 14; 19 | println!("{} - {}", kl2.planet, kl2.n_tentacles); // Venus - 14 20 | 21 | // ownership is transferred, original owner cannot access or change: 22 | // error: cannot assign to `klaatu.planet` because it is borrowed 23 | // klaatu.planet = "Pluto".to_string(); 24 | // error: cannot borrow `klaatu.planet` as immutable because `klaatu` is also borrowed as mutable 25 | // println!("{} - {}", klaatu.planet, klaatu.n_tentacles); 26 | } 27 | 28 | fn transform(a: Alien) -> Alien { 29 | Alien { planet:"".to_string(), n_tentacles:0 } 30 | } -------------------------------------------------------------------------------- /Chapter 6/code/ownership2.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/code/ref.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/code/ref_count_notgood.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/code/refcount.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/code/references.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/dangling_pointer.rs: -------------------------------------------------------------------------------- 1 | struct IntNumber<'a> { 2 | x: &'a i32, 3 | } 4 | 5 | fn main() { 6 | // n does not live long enough to be assigned to m 7 | // let m: &u32 = { 8 | // let n = &5u32; // error: borrowed value does not live long enough 9 | // n 10 | // }; 11 | // let o = *m; 12 | 13 | // The following will be rejected, since y has a shorter lifetime than x. 14 | let mut x = &3; 15 | { 16 | let mut y = 4; 17 | // x = &y; // error: `y` does not live long enough 18 | } // y is freed here, but x still lives... 19 | 20 | // 21 | let x = 1; // -+ x goes into scope 22 | // | 23 | { // | 24 | // let y = &5; // ---+ y goes into scope 25 | // let f = IntNumber { x: y }; // ---+ f goes into scope 26 | // x = &f.x; // | | error here 27 | } // ---+ f and y go out of scope 28 | // | 29 | println!("{}", x); // | 30 | } -------------------------------------------------------------------------------- /Chapter 6/exercises/grow_a_tentacle.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/increment_vector.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let p = vec![1, 2, 3]; 3 | let q = increment(p); 4 | print!("new vector: "); 5 | for x in &q { 6 | print!("{} ", x); 7 | } 8 | println!(""); 9 | 10 | let mut p = vec![1, 2, 3]; 11 | increment_mut(&mut p); 12 | print!("change in place: "); 13 | for x in &p { 14 | print!("{} ", x); 15 | } 16 | 17 | } 18 | 19 | fn increment_mut(v: &mut Vec) { 20 | for i in 0..v.len() { 21 | v[i] += 1; 22 | } 23 | } 24 | 25 | fn increment(mut v: Vec) -> Vec { 26 | for i in 0..v.len() { 27 | v[i] += 1; 28 | } 29 | v 30 | } 31 | // new vector: 2 3 4 32 | // change in place: 2 3 4 -------------------------------------------------------------------------------- /Chapter 6/exercises/ownership3.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 6/exercises/pointer_mutability.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | // through the mutable pointer the value of x has been changed: 3 | let mut x = 5; 4 | increment(&mut x); 5 | println!("x is now {}", x); 6 | 7 | // borrowed references cannot inherit mutability: 8 | // mut borrowed means: the reference can change, but not its value! 9 | let mut val1 = 10; 10 | let mut val2 = 20; 11 | let mut borrowed = &val1; 12 | borrowed = &val2; 13 | // *borrowed = 11; // error: cannot assign to immutable borrowed content `*borrowed` 14 | 15 | // references are type checked: 16 | let mut val1 = 10; 17 | let mut val3 = 10.0; 18 | let mut borrowed = &val1; 19 | // error: mismatched types: 20 | // expected `&_`, found `&_` (expected integral variable, found floating-point variable) [E0308] 21 | // borrowed = &val3; 22 | } 23 | 24 | fn increment(r: &mut isize) { 25 | *r += 1; 26 | println!("r is now {}", *r); 27 | } 28 | // r is now 6 29 | // x is now 6 30 | -------------------------------------------------------------------------------- /Chapter 7/code/builtin_macros.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let current_col = column!(); 3 | println!("defined on column: {}", current_col); 4 | 5 | let current_line = line!(); 6 | println!("defined on line: {}", current_line); 7 | 8 | let this_file = file!(); 9 | println!("defined in file: {}", this_file); 10 | 11 | not_ready(); 12 | } 13 | 14 | fn not_ready() { 15 | unimplemented!(); 16 | } 17 | // defined on column: 22 18 | // thread 'defined on line: 5 19 | // defined in file: F:\Rust\Rust book\The Rust Programming Language\Chapter 7 - Organizing code and macros\code\builtin_macros.rs 20 | //
' panicked at 'not yet implemented', F:\Rust\Rust book\The Rust Programming Language\Chapter 7 - Organizing code and macros\code\builtin_macros.rs:15 -------------------------------------------------------------------------------- /Chapter 7/code/cube/.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | Cargo.lock 3 | -------------------------------------------------------------------------------- /Chapter 7/code/cube/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "cube" 3 | version = "0.0.1" 4 | authors = ["Ivo Balbaert "] 5 | -------------------------------------------------------------------------------- /Chapter 7/code/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/code/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/code/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/code/import_modules.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/code/libmycrate.rlib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ivo-Balbaert/start_rust/58531d58b4950420b345f04c4e2d4e5aeb164c0e/Chapter 7/code/libmycrate.rlib -------------------------------------------------------------------------------- /Chapter 7/code/libstructs.rlib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ivo-Balbaert/start_rust/58531d58b4950420b345f04c4e2d4e5aeb164c0e/Chapter 7/code/libstructs.rlib -------------------------------------------------------------------------------- /Chapter 7/code/macro_debug.rs: -------------------------------------------------------------------------------- 1 | #![feature(trace_macros)] 2 | #![feature(log_syntax)] 3 | 4 | macro_rules! vector { 5 | ( 6 | $x:expr,$($y:expr),* 7 | ) => ( 8 | println!("New argument: {}", $x); 9 | log_syntax!(vector!($($y),*)); 10 | ); 11 | ( $x:expr ) => ( 12 | println!("New argument: {}", $x); 13 | ) 14 | } 15 | 16 | fn main() { 17 | trace_macros!(true); 18 | vector!(1, 2, 3, 12); 19 | } -------------------------------------------------------------------------------- /Chapter 7/code/macros.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 | mac1![42]; // arg is 42 54 | printall!("hello", 42, 3.14); // hello / 42 / 3.14 / 55 | fn1(); 56 | // massert!(1 == 42); 57 | 58 | let v = [10, 40, 30]; 59 | massert!(v.contains(&30)); 60 | massert!(!v.contains(&50)); 61 | unless!(v.contains(&25), println!("v does not contain 25")); 62 | 63 | } 64 | // Welcome to the Game! 65 | // arg is 42 66 | // arg is 42 67 | // hello / 42 / 3.14 / Called the function "fn1"() 68 | // thread '
' panicked at 'Assertion failed!' 69 | // v does not contain 25 -------------------------------------------------------------------------------- /Chapter 7/code/mod_private.rs: -------------------------------------------------------------------------------- 1 | mod library { 2 | pub struct Interface { 3 | m_impl: Impl 4 | } 5 | 6 | impl Interface { 7 | pub fn new() -> Interface { 8 | Interface{ m_impl: Impl } 9 | } 10 | 11 | pub fn f(&self){ 12 | self.m_impl.f(); 13 | } 14 | } 15 | 16 | struct Impl; 17 | 18 | impl Impl { 19 | pub fn f(&self){ 20 | println!("f"); 21 | } 22 | } 23 | } 24 | 25 | fn main() { 26 | let o = library::Interface::new(); 27 | o.f(); 28 | } -------------------------------------------------------------------------------- /Chapter 7/code/modul1/mod.rs: -------------------------------------------------------------------------------- 1 | pub fn func1() { 2 | println!("called func1 from modul1"); 3 | } 4 | -------------------------------------------------------------------------------- /Chapter 7/code/modul2.rs: -------------------------------------------------------------------------------- 1 | pub fn func1() { 2 | println!("called func1 from modul2"); 3 | } -------------------------------------------------------------------------------- /Chapter 7/code/modules.rs: -------------------------------------------------------------------------------- 1 | use game1::func2; 2 | use game1::func2 as gf2; 3 | // use game1::{func2, func3}; 4 | // pub use game1::{func2, func3}; // visible in the super level 5 | // use game1::*; 6 | use game1::subgame1::subfunc1 as sf1; 7 | 8 | mod game1 { 9 | // all of the module's code items go in here 10 | fn func1() { // private function 11 | println!("Am I visible?"); 12 | } 13 | 14 | pub fn func2() { 15 | println!("You called func2 in game1!"); 16 | } 17 | 18 | pub fn func3() { 19 | println!("You called func2 in game1!"); 20 | } 21 | 22 | pub mod subgame1 { 23 | pub fn subfunc1() { 24 | println!("You called subfunc1 in subgame1!"); 25 | } 26 | } 27 | 28 | pub struct Magician { 29 | pub name: String, 30 | pub age: i32, 31 | power: i32 32 | } 33 | } 34 | 35 | fn main() { 36 | // game1::func1(); // error: function `func1` is private 37 | game1::func2(); // works without the use import 38 | self::game1::func2(); 39 | ::game1::func2(); 40 | // super::game1::func2(); // unresolved name 41 | 42 | // calling a nested module: 43 | game1::subgame1::subfunc1(); 44 | 45 | // importing a function or module with use: 46 | func2(); 47 | gf2(); 48 | sf1(); 49 | 50 | // error: field `power` of struct `game1::Magician` is private 51 | // let mag1 = game1::Magician { name: "Gandalf".to_string(), age: 725, power: 98}; 52 | } 53 | 54 | // You called func2 in game1! 55 | // You called subfunc1 in subgame1! 56 | // You called func2 in game1! 57 | // You called func2 in game1! 58 | // You called subfunc1 in subgame1! -------------------------------------------------------------------------------- /Chapter 7/code/monsters/.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | Cargo.lock 3 | -------------------------------------------------------------------------------- /Chapter 7/code/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/code/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/code/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/code/random/.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | -------------------------------------------------------------------------------- /Chapter 7/code/random/Cargo.lock: -------------------------------------------------------------------------------- 1 | [root] 2 | name = "random" 3 | version = "0.0.1" 4 | dependencies = [ 5 | "rand 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 6 | ] 7 | 8 | [[package]] 9 | name = "libc" 10 | version = "0.1.8" 11 | source = "registry+https://github.com/rust-lang/crates.io-index" 12 | 13 | [[package]] 14 | name = "rand" 15 | version = "0.3.8" 16 | source = "registry+https://github.com/rust-lang/crates.io-index" 17 | dependencies = [ 18 | "libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", 19 | ] 20 | 21 | -------------------------------------------------------------------------------- /Chapter 7/code/random/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | 3 | name = "random" 4 | version = "0.0.1" 5 | authors = ["Ivo Balbaert "] 6 | 7 | [dependencies] 8 | rand = "*" -------------------------------------------------------------------------------- /Chapter 7/code/random/src/main.rs: -------------------------------------------------------------------------------- 1 | extern crate rand; 2 | use rand::Rng; 3 | 4 | fn main() { 5 | println!("Give me 5 random numbers:"); 6 | for _ in 0..5 { 7 | let rnd = rand::random::(); 8 | print!("{} / ", rnd); 9 | } 10 | println!(""); 11 | println!("Give me 5 positive random numbers smaller than 32:"); 12 | for _ in 0..5 { 13 | let rnd = (rand::random::() % 32) + 1; 14 | print!("{} / ", rnd); 15 | } 16 | println!(""); 17 | 18 | let mut rng = rand::thread_rng(); 19 | if rng.gen() { // random bool 20 | println!("i32: {}, u32: {}", rng.gen::(), rng.gen::()) 21 | } 22 | 23 | // generate a random number in a range, for example: 1 - 100: 24 | let secret_number = rand::thread_rng().gen_range(1, 101); 25 | println!("The secret number is: {}", secret_number); 26 | 27 | let tuple = rand::random::<(f64, char)>(); 28 | println!("{:?}", tuple); 29 | 30 | // generate a random string: 31 | let mut str = String::new(); 32 | for _ in (0..10) { 33 | str.push(rand::random::() as char); 34 | } 35 | println!("{:?}", str); 36 | 37 | } 38 | // Give me 5 random numbers: 39 | // -1786096291 / -312872251 / 959357270 / 1391515785 / -1379700184 / 40 | // Give me 5 positive random numbers smaller than 32: 41 | // 11 / 15 / 28 / 13 / 23 / 42 | // The secret number is: 16 43 | // (0.279622, '\u{583cf}') 44 | // "n\u{1b}\u{8a}\u{98}\"\u{d2}c\u{ee}\u{a8}I" -------------------------------------------------------------------------------- /Chapter 7/code/structs.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/macro_ex.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 | macro_rules! says { 18 | ($x:expr) => { 19 | println!("He/She sais: '{}'", $x); 20 | }; 21 | ($x:expr, $y:expr) => { 22 | println!("He/She sais: '{}' to {}", $x, $y); 23 | }; 24 | } 25 | 26 | 27 | fn main() { 28 | println!("{}", mac2!(5)); // 15 29 | println!("{}", mac2!(2 + 3)); // 15 30 | mac3!(x); // expands into let x = 42; 31 | println!("{}", x); // 42 32 | mac4!("Where am I?"); // start - Where am I? - end 33 | println!(""); 34 | says!("Hi"); 35 | says!("Hi", "Jim"); 36 | } 37 | // 15 38 | // 15 39 | // 42 40 | // start - Where am I? - end 41 | // He/She sais: 'Hi' 42 | // He/She sais: 'Hi' to Jim -------------------------------------------------------------------------------- /Chapter 7/exercises/priv_struct.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/code/change_vec.rs: -------------------------------------------------------------------------------- 1 | use std::thread; 2 | use std::sync::{Arc, Mutex}; 3 | 4 | fn main() { 5 | let mut magicians = Arc::new(Mutex::new(vec!["Morgan".to_string(), 6 | "Allanon".to_string(), "Jafar".to_string()])); 7 | 8 | for i in 0..3 { 9 | let magicians = magicians.clone(); 10 | thread::spawn(move || { 11 | let mut mags = magicians.lock(); 12 | match mags { 13 | Ok(mut mags) => 14 | { 15 | let mut temp = mags[i].to_string(); 16 | temp.push_str("ius"); 17 | mags[i] = temp; 18 | }, 19 | Err(str) => println!("{}", str) 20 | } 21 | }).join(); 22 | } 23 | println!("{:?} - ", *magicians); 24 | print!("{:?} - ", *magicians.lock().unwrap()); 25 | } 26 | // Mutex { data: ["Morganius", "Allanonius", "Jafarius"] } - [Finished in 29.6s] 27 | // ["Morganius", "Allanonius", "Jafarius"] -------------------------------------------------------------------------------- /Chapter 8/code/channel_box.rs: -------------------------------------------------------------------------------- 1 | use std::thread; 2 | use std::sync::mpsc; 3 | 4 | trait Message : Send { 5 | fn print(&self); 6 | } 7 | 8 | struct Msg1 { 9 | value: i32 10 | } 11 | 12 | impl Message for Msg1 { 13 | fn print(&self) { 14 | println!("value: {:?}", self.value); 15 | } 16 | } 17 | 18 | fn main() { 19 | let (tx, rx) = mpsc::channel::>(); 20 | 21 | let handle = thread::spawn(move|| { 22 | let msg = rx.recv().unwrap(); 23 | msg.print(); 24 | }); 25 | 26 | let msg = Box::new(Msg1{ value:1 }); 27 | tx.send(msg).unwrap(); 28 | 29 | handle.join().ok(); 30 | } 31 | // value: 1 -------------------------------------------------------------------------------- /Chapter 8/code/channels.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/code/channels2.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/code/channels_struct.rs: -------------------------------------------------------------------------------- 1 | use std::thread; 2 | use std::sync::mpsc; 3 | 4 | struct Block { 5 | value: i32 6 | } 7 | 8 | fn main() { 9 | let (tx1, rx1) = mpsc::channel::(); 10 | let (tx2, rx2) = mpsc::channel::(); 11 | 12 | thread::spawn(move|| { 13 | let mut block = rx1.recv().unwrap(); 14 | println!("Input: {:?}", block.value); 15 | 16 | block.value += 1; 17 | tx2.send(block).unwrap(); 18 | }); 19 | 20 | let input = Block{ value: 1 }; 21 | tx1.send(input).unwrap(); 22 | 23 | let output = rx2.recv().unwrap(); 24 | println!("Output: {:?}", output.value); 25 | } 26 | // Input: 1 27 | // Output: 2 -------------------------------------------------------------------------------- /Chapter 8/code/make_channel.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/code/many_threads.rs: -------------------------------------------------------------------------------- 1 | use std::thread; 2 | 3 | static NTHREADS: i32 = 10000; 4 | 5 | fn main() { 6 | println!("************************** Before the start of the threads"); 7 | for i in 0..NTHREADS { 8 | thread::spawn(move || { 9 | println!("this is thread number {}", i) 10 | }); 11 | } 12 | println!("************************** All threads finished!"); 13 | } -------------------------------------------------------------------------------- /Chapter 8/code/many_threads/.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | -------------------------------------------------------------------------------- /Chapter 8/code/many_threads/Cargo.lock: -------------------------------------------------------------------------------- 1 | [root] 2 | name = "many_threads" 3 | version = "0.1.0" 4 | dependencies = [ 5 | "num_cpus 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 6 | "threadpool 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 7 | ] 8 | 9 | [[package]] 10 | name = "libc" 11 | version = "0.1.6" 12 | source = "registry+https://github.com/rust-lang/crates.io-index" 13 | 14 | [[package]] 15 | name = "num_cpus" 16 | version = "0.2.2" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | dependencies = [ 19 | "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 20 | ] 21 | 22 | [[package]] 23 | name = "threadpool" 24 | version = "0.1.4" 25 | source = "registry+https://github.com/rust-lang/crates.io-index" 26 | 27 | -------------------------------------------------------------------------------- /Chapter 8/code/many_threads/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/code/many_threads/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/code/moving_closure.rs: -------------------------------------------------------------------------------- 1 | use std::thread; 2 | 3 | fn main() { 4 | read(); 5 | } 6 | 7 | fn read() { 8 | let book = read_book("book1.txt"); 9 | // error: closure may outlive the current function, but it borrows `book`, 10 | // which is owned by the current function 11 | // thread::spawn(|| { 12 | // println!("{:?}", book); 13 | // }); 14 | 15 | thread::spawn(move || { 16 | println!("{:?}", book); 17 | }); 18 | } 19 | 20 | fn read_book(s: &str) { } 21 | -------------------------------------------------------------------------------- /Chapter 8/code/not_shared.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/code/panic_thread.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/code/sync_channel.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/code/thread_safe.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(); 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/code/thread_spawn.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/exc_thread_safe.rs: -------------------------------------------------------------------------------- 1 | use std::thread; 2 | use std::sync::{Arc, Mutex}; 3 | 4 | fn main() { 5 | let data = Arc::new(Mutex::new( vec![7, 13, 42] )); 6 | (0..3).map(|i| { 7 | let mutex = data.clone(); 8 | thread::spawn(move || { 9 | let mut vec = mutex.lock().unwrap(); 10 | vec[i] *= 3; 11 | }).join() 12 | }).collect::>(); 13 | println!("{:?}", *data.lock().unwrap()); 14 | } 15 | // [21, 39, 126] 16 | -------------------------------------------------------------------------------- /Chapter 8/exercises/shared_channel.rs: -------------------------------------------------------------------------------- 1 | use std::thread; 2 | use std::sync::mpsc; 3 | 4 | static NTHREADS: usize = 8; 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 4 done 27 | // thread 1 done 28 | // thread 5 done 29 | // thread 7 done 30 | // thread 2 done 31 | // thread 3 done 32 | // thread 6 done 33 | // [6, 1, 0, 4, 5, 7, 2, 3] -------------------------------------------------------------------------------- /Chapter 9/code/arguments.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/code/asm.rs: -------------------------------------------------------------------------------- 1 | // error: use of unstable library feature 'asm' 2 | // help: add #![feature(asm)] to the crate attributes to enable 3 | #![feature(asm)] 4 | 5 | fn subtract(a: i32, b: i32) -> i32 { 6 | let sub: i32; 7 | unsafe { 8 | asm!("sub $2, $1; mov $1, $0" 9 | : "=r"(sub) 10 | : "r"(a), "r"(b) 11 | ); 12 | } 13 | sub 14 | } 15 | 16 | fn main() { 17 | println!("{}", subtract(42, 7)) // 35 18 | } -------------------------------------------------------------------------------- /Chapter 9/code/calling_clibrary.rs: -------------------------------------------------------------------------------- 1 | #[repr(C)] 2 | #[derive(Copy, Clone, Debug)] 3 | struct Complex { 4 | re: f32, 5 | im: f32, 6 | } 7 | 8 | #[link(name = "m")] 9 | extern { 10 | fn ctanf(z: Complex) -> Complex; 11 | } 12 | 13 | fn tan(z: Complex) -> Complex { 14 | unsafe { ctanf(z) } 15 | } 16 | 17 | fn main() { 18 | let z = Complex { re: -1., im: 1. }; // z is -1 + i 19 | let z_tan = tan(z); 20 | println!("the tangens of {:?} is {:?}", z, z_tan); 21 | } 22 | // the tangens of Complex { re: -1, im: 1 } is Complex { re: -0.271753, im: 1.083923 } -------------------------------------------------------------------------------- /Chapter 9/code/calling_libc.rs: -------------------------------------------------------------------------------- 1 | // beta 4: error: unstable feature 2 | #![feature(libc)] 3 | 4 | extern crate libc; 5 | use libc::puts; 6 | use std::ffi::CString; 7 | 8 | fn main() { 9 | let sentence = "Merlin is the greatest magician!"; 10 | let to_print = CString::new(sentence).unwrap(); 11 | unsafe { 12 | puts(to_print.as_ptr()); 13 | } 14 | } 15 | // Merlin is the greatest magician! -------------------------------------------------------------------------------- /Chapter 9/code/parsing_argument.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | if let Some(arg1) = std::env::args().nth(1) { 3 | if let Ok(x) = arg1.parse::() { 4 | println!("Got it: {}", x); 5 | } else { 6 | println!("I wasn't given an integer!"); 7 | } 8 | } else { 9 | println!("I wasn't given an argument!"); 10 | } 11 | } -------------------------------------------------------------------------------- /Chapter 9/code/pointer_offset.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let items = [1u32, 2, 3, 4]; 3 | let ptr = &items[1] as *const u32; 4 | println!("{}", unsafe { *ptr }); 5 | println!("{}", unsafe { *ptr.offset(-1) }); 6 | println!("{}", unsafe { *ptr.offset(1) }); 7 | // error: binary operation `+` cannot be applied to type `*const u32` [E0369] 8 | // println!("{}", unsafe { ptr + 2}); 9 | } 10 | // 2 11 | // 1 12 | // 3 13 | -------------------------------------------------------------------------------- /Chapter 9/code/raw_pointers.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/code/size_of_val.rs: -------------------------------------------------------------------------------- 1 | use std::mem; 2 | 3 | fn main() { 4 | let arr = ["Rust", "Go", "Swift"]; 5 | println!("array arr occupies {} bytes", mem::size_of_val(&arr)); 6 | println!("The size of an isize: {} bytes", mem::size_of::()); 7 | } 8 | // array arr occupies 48 bytes 9 | // The size of an isize: 8 bytes -------------------------------------------------------------------------------- /Chapter 9/code/swap.rs: -------------------------------------------------------------------------------- 1 | use std::mem; 2 | 3 | fn main() { 4 | let mut n = 0; 5 | let mut m = 1; 6 | mem::swap(&mut n, &mut m); 7 | println!("n: {} m: {}", n, m); 8 | } 9 | // n: 1 m: 0 10 | -------------------------------------------------------------------------------- /Chapter 9/code/unsafe.rs: -------------------------------------------------------------------------------- 1 | use std::mem; 2 | 3 | static mut n: i32 = 42; 4 | 5 | fn main() { 6 | let v: &[u8] = unsafe { 7 | mem::transmute("Gandalf") 8 | }; 9 | println!("{:?}", v); 10 | 11 | // reading or changing a static mutable variable: 12 | unsafe { 13 | println!("{:?}", n ); // 42 14 | n = 108; 15 | } 16 | } 17 | // [71, 97, 110, 100, 97, 108, 102] -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | start_rust 2 | ========================= 3 | 4 | Contains the code of the book: "Rust Essentials", by Ivo Balbaert (Packt Publishing, May 2015) 5 | Reviewed for Rust 1.2.0 6 | --------------------------------------------------------------------------------