Preface What this book covers What you need for this book Who this book is for Conventions Reader feedback Customer support Downloading the example code Errata Piracy Questions Introducing and Installing Rust Installing Rust Installing rustup on Linux gcc prerequisites Testing your installation Integrated Development Environment Your first Rust project Structure of a Rust project Automating things Creating a binary package using Cargo Using Cargo to build and run an application Cleaning your source tree with Cargo Creating documentation using Cargo rustdoc versus Cargo Using Cargo to help with your unit testing Assert yourself! Is there anything Cargo can't do? Summary Variables Variable mutability Creating a variable How can we tell the compiler that we want x to be an int? Defining other variable types Float Signed and unsigned integers Const and static Defining the variable value before use Strings How Rust uses memory Back to Strings String slices What's with the warnings? Using the format! macro Building a string Code review Casting String methods Generics and arrays Arrays Array performance Vectors Creating a vector with an initial size Creating a vector via an iterator Adding and removing from the vector Manipulating an array or vector via slices Passing values around Passing by value Passing by reference The reference type A practical example Summary Input and Output Functions and methods in Rust The difference between println! and println Introduction to the standard library The libraries Controlling the output formatting Positioning the output Named parameters Specifying the argument types Formatting traits Formatting parameters Getting information in Command-line arguments Handling files Reading from a file Loading a file Writing a file The use of expect XML and Rust Reading a file Writing a file Summary Conditions, Recursion, and Loops Loops The for loop Using enumerate The _ parameter The simple loop The while condition Prematurely terminating a loop Using loop labels Recursive functions What is the difference between having and not having a semicolon? Summary Remember, Remember Let's start at the beginning The stack frame What is meant by the stack? Let's consider the heap Deallocation What about functions with arguments? Static memory allocation Garbage collecting time and ownership An owned pointer example Comparison to C Let's revisit some old code Let's not race ahead! Stop the race... Summary Creating Your Own Rust Applications Project 1 - let's start with some math Requirements Supplied data Application output Project 2 - some text manipulation Requirements Code notes Project 3 – area and volume Shape types Volume or area User-defined shape Formulae for calculations Testing criteria Auto-documentation Using regular expressions (regex) Input and output Project 4 – memory Bitwise rotation Rotation caveat Output Summary Matching and Structures Structs 101 Variables, variables everywhere The structure of a struct Smaller is better Accessing a struct Defining the child structures Multi-file version Private versus public fields Structs 102 Tuples Using a tuple to define a variable Tuple indexing Destructuring with let Tuple structs – the hybrid of two The single element tuple struct Back to the unit-like struct Enumerations Accessing enumeration members The two questions you should be asking Patterns and matching Matching Let's really make the function simple Using match with an enum Ignoring a parameter with match Fall through patterns Ranges Creating a binding within a match pattern Let's add an if into the mix Using match with a compound type And back to if let Summary The Rust Application Lifetime What are they? Ownership Borrowing Lifetime Ownership in Rust Abstractions Ownership – from the beginning Variable binding Stack and heap variables Why is this important? The Copy trait Borrowing in Rust Borrow immutability Mutable borrows The Rust borrowing rules Fixing the problem Think about the scope It's all for your own good The lifetime The mythical bank account The lifetime variable - ' Lifetime of other types Lifetime within an struct Multiple lifetimes Always consider the scope 'struct Input and output lifetimes Input only Output only Input and output Summary Introducing Generics, Impl, and Traits Generics 101 Understanding the error A generic problem The unsafe directive The whole #! Traits and Impl Impl The impl lifetime And back to traits we go... A simple crate example Traits and generics Defining the impl for specific types Using where Making it work Something you may have noticed Generics - a small aside So what does happen? Back to the where version Try to compile Trait bounds Can we reduce the amount of code further? Can the default method be overridden? Rounding off traits Inheritance Deriving Trait objects Let's create a sample test setup Let's see dynamic dispatch Keeping your object safe Summary Creating Your Own Crate What exactly is a crate? Looking at modules I can see a problem with this analogy Back to our math library Using a useful name Let's create! Creating top-level modules The multifile module What about submodules? The mod.rs file Let's add some code Beware of double name scopes Adding unit tests to the library Making something public Let's give our crate a quick run out External dependencies Changing the scope Altering the crate name Optimizing your use statements The use-everything approach The you-decide approach The use-me approach The use-me-but-call-me-something-else approach The use-glob approach The use-glob-self approach Summary Concurrency in Rust A bit of a story What was that all about? Send Sync When is an immutable variable not an immutable variable? And it's obviously mutable, it has mut in the definition Interior mutability Back to sync A beginner's guide to threading in Rust An easy approach to thinking about how threads work. Joining threads Closures Closures aren't all they first appear to be Closures as function arguments Closures with explicit lifetimes – a special case Returning a closure What is the move parameter? Back to threading Ownership has its advantages The reference counter Problem solved – use Mutex Why do we put the thread to sleep? Thread synchronization Thread panics Summary Now It's Your Turn! Task 1 – cleaning the code (part 1) The problems with each option The String option The struct option The task Task 2 – cleaning the code (part 2) The task Task 3 – extending the crate (part 1) The task Task 4 – extending the crate (part 2) Summary The Standard Library Chapter format What is the standard library? The standard modules (overview) Primitive types (overview) Macros (overview) Prelude The standard modules std::Any std::ascii std::borrow std::boxed std::cell std::char std::clone std::cmp std::collections std::convert std::default std:env std:error std::f32 std::f64 std:ffi std::fmt std::fs std::hash std::i8 std::i16 std::i32 std::i64 std::io std::isize std::iter std::marker std::mem std:net std::num std::os std::panic std::path std::process std::ptr std::slice std::str std::string std::sync std::thread std::time std::u8 std::u16 std::u32 std::u64 std::usize std::vec Summary Foreign Function Interfaces Introducing our simple library The three-step program Including the dependency Creating the code What's the [link(name="")] for? What's the big deal? That was simple enough! Let's extend things a bit What happens if the types don't match? Can we make things safer? Wrappers A practical example Accessing global variables Cleaning up after yourself Drop it! Monitoring an external process within an FFI Targeting synchronous callbacks Targeting a Rust object Calling Rust from another language Dealing with the unknown C structs Summary