The Rust Programming Language, 2nd Edition

Book description

The Rust Programming Language, 2nd Edition is the official guide to Rust 2021: an open source systems programming language that will help you write faster, more reliable software. Rust provides control of low-level details along with high-level ergonomics, allowing you to improve productivity and eliminate the hassle traditionally associated with low-level languages.

Klabnik and Nichols, alumni of the Rust Core Team, share their knowledge to help you get the most out of Rust's features so that you can create robust and scalable programs. You'll begin with basics like creating functions, choosing data types, and binding variables, then move on to more advanced concepts, such as:

—Ownership and borrowing, lifetimes, generics, traits, and trait objects to communicate your program's constraints to the compiler

—Smart pointers and multithreading, and how ownership interacts with them to enable fearless concurrency

—How to use Cargo, Rust's built-in package manager, to build, document your code, and manage dependencies

—The best ways to test, handle errors, refactor, and take advantage of expressive pattern matching

In addition to the countless code examples, you'll find three chapters dedicated to building complete projects: a number-guessing game, a Rust implementation of a command line tool, and a multithreaded server.

Table of contents

  1. Title Page
  2. Copyright
  3. About the Authors
  4. Foreword
  5. Preface
  6. Acknowledgments
  7. Introduction
    1. Who Rust Is For
      1. Teams of Developers
      2. Students
      3. Companies
      4. Open Source Developers
      5. People Who Value Speed and Stability
    2. Who This Book Is For
    3. How to Use This Book
    4. Resources and How to Contribute to This Book
  8. Chapter 1: Getting Started
    1. Installation
      1. Installing rustup on Linux or macOS
      2. Installing rustup on Windows
      3. Troubleshooting
      4. Updating and Uninstalling
      5. Local Documentation
    2. Hello, World!
      1. Creating a Project Directory
      2. Writing and Running a Rust Program
      3. Anatomy of a Rust Program
      4. Compiling and Running Are Separate Steps
    3. Hello, Cargo!
      1. Creating a Project with Cargo
      2. Building and Running a Cargo Project
      3. Building for Release
      4. Cargo as Convention
    4. Summary
  9. Chapter 2: Programming a Guessing Game
    1. Setting Up a New Project
    2. Processing a Guess
      1. Storing Values with Variables
      2. Receiving User Input
      3. Handling Potential Failure with Result
      4. Printing Values with println! Placeholders
      5. Testing the First Part
    3. Generating a Secret Number
      1. Using a Crate to Get More Functionality
      2. Generating a Random Number
    4. Comparing the Guess to the Secret Number
    5. Allowing Multiple Guesses with Looping
      1. Quitting After a Correct Guess
      2. Handling Invalid Input
    6. Summary
  10. Chapter 3: Common Programming Concepts
    1. Variables and Mutability
      1. Constants
      2. Shadowing
    2. Data Types
      1. Scalar Types
      2. Compound Types
    3. Functions
      1. Parameters
      2. Statements and Expressions
      3. Functions with Return Values
    4. Comments
    5. Control Flow
      1. if Expressions
      2. Repetition with Loops
    6. Summary
  11. Chapter 4: Understanding Ownership
    1. What Is Ownership?
      1. Ownership Rules
      2. Variable Scope
      3. The String Type
      4. Memory and Allocation
      5. Ownership and Functions
      6. Return Values and Scope
    2. References and Borrowing
      1. Mutable References
      2. Dangling References
      3. The Rules of References
    3. The Slice Type
      1. String Slices
      2. Other Slices
    4. Summary
  12. Chapter 5: Using Structs to Structure Related Data
    1. Defining and Instantiating Structs
      1. Using the Field Init Shorthand
      2. Creating Instances from Other Instances with Struct Update Syntax
      3. Using Tuple Structs Without Named Fields to Create Different Types
      4. Unit-Like Structs Without Any Fields
    2. An Example Program Using Structs
      1. Refactoring with Tuples
      2. Refactoring with Structs: Adding More Meaning
      3. Adding Useful Functionality with Derived Traits
    3. Method Syntax
      1. Defining Methods
      2. Methods with More Parameters
      3. Associated Functions
      4. Multiple impl Blocks
    4. Summary
  13. Chapter 6: Enums and Pattern Matching
    1. Defining an Enum
      1. Enum Values
      2. The Option Enum and Its Advantages Over Null Values
    2. The match Control Flow Construct
      1. Patterns That Bind to Values
      2. Matching with Option<T>
      3. Matches Are Exhaustive
      4. Catch-All Patterns and the _ Placeholder
    3. Concise Control Flow with if let
    4. Summary
  14. Chapter 7: Managing Growing Projects with Packages, Crates, and Modules
    1. Packages and Crates
    2. Defining Modules to Control Scope and Privacy
    3. Paths for Referring to an Item in the Module Tree
      1. Exposing Paths with the pub Keyword
      2. Starting Relative Paths with super
      3. Making Structs and Enums Public
    4. Bringing Paths into Scope with the use Keyword
      1. Creating Idiomatic use Paths
      2. Providing New Names with the as Keyword
      3. Re-exporting Names with pub use
      4. Using External Packages
      5. Using Nested Paths to Clean Up Large use Lists
      6. The Glob Operator
    5. Separating Modules into Different Files
    6. Summary
  15. Chapter 8: Common Collections
    1. Storing Lists of Values with Vectors
      1. Creating a New Vector
      2. Updating a Vector
      3. Reading Elements of Vectors
      4. Iterating Over the Values in a Vector
      5. Using an Enum to Store Multiple Types
      6. Dropping a Vector Drops Its Elements
    2. Storing UTF-8 Encoded Text with Strings
      1. What Is a String?
      2. Creating a New String
      3. Updating a String
      4. Indexing into Strings
      5. Slicing Strings
      6. Methods for Iterating Over Strings
      7. Strings Are Not So Simple
    3. Storing Keys with Associated Values in Hash Maps
      1. Creating a New Hash Map
      2. Accessing Values in a Hash Map
      3. Hash Maps and Ownership
      4. Updating a Hash Map
      5. Hashing Functions
    4. Summary
  16. Chapter 9: Error Handling
    1. Unrecoverable Errors with panic!
    2. Recoverable Errors with Result
      1. Matching on Different Errors
      2. Propagating Errors
    3. To panic! or Not to panic!
      1. Examples, Prototype Code, and Tests
      2. Cases in Which You Have More Information Than the Compiler
      3. Guidelines for Error Handling
      4. Creating Custom Types for Validation
    4. Summary
  17. Chapter 10: Generic Types, Traits, and Lifetimes
    1. Removing Duplication by Extracting a Function
    2. Generic Data Types
      1. In Function Definitions
      2. In Struct Definitions
      3. In Enum Definitions
      4. In Method Definitions
      5. Performance of Code Using Generics
    3. Traits: Defining Shared Behavior
      1. Defining a Trait
      2. Implementing a Trait on a Type
      3. Default Implementations
      4. Traits as Parameters
      5. Returning Types That Implement Traits
      6. Using Trait Bounds to Conditionally Implement Methods
    4. Validating References with Lifetimes
      1. Preventing Dangling References with Lifetimes
      2. The Borrow Checker
      3. Generic Lifetimes in Functions
      4. Lifetime Annotation Syntax
      5. Lifetime Annotations in Function Signatures
      6. Thinking in Terms of Lifetimes
      7. Lifetime Annotations in Struct Definitions
      8. Lifetime Elision
      9. Lifetime Annotations in Method Definitions
      10. The Static Lifetime
    5. Generic Type Parameters, Trait Bounds, and Lifetimes Together
    6. Summary
  18. Chapter 11: Writing Automated Tests
    1. How to Write Tests
      1. The Anatomy of a Test Function
      2. Checking Results with the assert! Macro
      3. Testing Equality with the assert_eq! and assert_ne! Macros
      4. Adding Custom Failure Messages
      5. Checking for Panics with should_panic
      6. Using Result<T, E> in Tests
    2. Controlling How Tests Are Run
      1. Running Tests in Parallel or Consecutively
      2. Showing Function Output
      3. Running a Subset of Tests by Name
      4. Ignoring Some Tests Unless Specifically Requested
    3. Test Organization
      1. Unit Tests
      2. Integration Tests
    4. Summary
  19. Chapter 12: An I/O Project: Building a Command Line Program
    1. Accepting Command Line Arguments
      1. Reading the Argument Values
      2. Saving the Argument Values in Variables
    2. Reading a File
    3. Refactoring to Improve Modularity and Error Handling
      1. Separation of Concerns for Binary Projects
      2. Fixing the Error Handling
      3. Extracting Logic from main
      4. Splitting Code into a Library Crate
    4. Developing the Library’s Functionality with Test-Driven Development
      1. Writing a Failing Test
      2. Writing Code to Pass the Test
    5. Working with Environment Variables
      1. Writing a Failing Test for the Case-Insensitive Search Function
      2. Implementing the search_case_insensitive Function
    6. Writing Error Messages to Standard Error Instead of Standard Output
      1. Checking Where Errors Are Written
      2. Printing Errors to Standard Error
    7. Summary
  20. Chapter 13: Functional Language Features: Iterators and Closures
    1. Closures: Anonymous Functions That Capture Their Environment
      1. Capturing the Environment with Closures
      2. Closure Type Inference and Annotation
      3. Capturing References or Moving Ownership
      4. Moving Captured Values Out of Closures and the Fn Traits
    2. Processing a Series of Items with Iterators
      1. The Iterator Trait and the next Method
      2. Methods That Consume the Iterator
      3. Methods That Produce Other Iterators
      4. Using Closures That Capture Their Environment
    3. Improving Our I/O Project
      1. Removing a clone Using an Iterator
      2. Making Code Clearer with Iterator Adapters
      3. Choosing Between Loops and Iterators
    4. Comparing Performance: Loops vs. Iterators
    5. Summary
  21. Chapter 14: More About Cargo and Crates.io
    1. Customizing Builds with Release Profiles
    2. Publishing a Crate to Crates.io
      1. Making Useful Documentation Comments
      2. Exporting a Convenient Public API with pub use
      3. Setting Up a Crates.io Account
      4. Adding Metadata to a New Crate
      5. Publishing to Crates.io
      6. Publishing a New Version of an Existing Crate
      7. Deprecating Versions from Crates.io with cargo yank
    3. Cargo Workspaces
      1. Creating a Workspace
      2. Creating the Second Package in the Workspace
    4. Installing Binaries with cargo install
    5. Extending Cargo with Custom Commands
    6. Summary
  22. Chapter 15: Smart Pointers
    1. Using Box<T> to Point to Data on the Heap
      1. Using Box<T> to Store Data on the Heap
      2. Enabling Recursive Types with Boxes
    2. Treating Smart Pointers Like Regular References with Deref
      1. Following the Pointer to the Value
      2. Using Box<T> Like a Reference
      3. Defining Our Own Smart Pointer
      4. Implementing the Deref Trait
      5. Implicit Deref Coercions with Functions and Methods
      6. How Deref Coercion Interacts with Mutability
    3. Running Code on Cleanup with the Drop Trait
    4. Rc<T>, the Reference Counted Smart Pointer
      1. Using Rc<T> to Share Data
      2. Cloning an Rc<T> Increases the Reference Count
    5. RefCell<T> and the Interior Mutability Pattern
      1. Enforcing Borrowing Rules at Runtime with RefCell<T>
      2. Interior Mutability: A Mutable Borrow to an Immutable Value
      3. Allowing Multiple Owners of Mutable Data with Rc<T> and RefCell<T>
    6. Reference Cycles Can Leak Memory
      1. Creating a Reference Cycle
      2. Preventing Reference Cycles Using Weak<T>
    7. Summary
  23. Chapter 16: Fearless Concurrency
    1. Using Threads to Run Code Simultaneously
      1. Creating a New Thread with spawn
      2. Waiting for All Threads to Finish Using join Handles
      3. Using move Closures with Threads
    2. Using Message Passing to Transfer Data Between Threads
      1. Channels and Ownership Transference
      2. Sending Multiple Values and Seeing the Receiver Waiting
      3. Creating Multiple Producers by Cloning the Transmitter
    3. Shared-State Concurrency
      1. Using Mutexes to Allow Access to Data from One Thread at a Time
      2. Similarities Between RefCell<T>/Rc<T> and Mutex<T>/Arc<T>
    4. Extensible Concurrency with the Send and Sync Traits
      1. Allowing Transference of Ownership Between Threads with Send
      2. Allowing Access from Multiple Threads with Sync
      3. Implementing Send and Sync Manually Is Unsafe
    5. Summary
  24. Chapter 17: Object-Oriented Programming Features
    1. Characteristics of Object-Oriented Languages
      1. Objects Contain Data and Behavior
      2. Encapsulation That Hides Implementation Details
      3. Inheritance as a Type System and as Code Sharing
    2. Using Trait Objects That Allow for Values of Different Types
      1. Defining a Trait for Common Behavior
      2. Implementing the Trait
      3. Trait Objects Perform Dynamic Dispatch
    3. Implementing an Object-Oriented Design Pattern
      1. Defining Post and Creating a New Instance in the Draft State
      2. Storing the Text of the Post Content
      3. Ensuring the Content of a Draft Post Is Empty
      4. Requesting a Review Changes the Post’s State
      5. Adding approve to Change the Behavior of content
      6. Trade-offs of the State Pattern
    4. Summary
  25. Chapter 18: Patterns and Matching
    1. All the Places Patterns Can Be Used
      1. match Arms
      2. Conditional if let Expressions
      3. while let Conditional Loops
      4. for Loops
      5. let Statements
      6. Function Parameters
    2. Refutability: Whether a Pattern Might Fail to Match
    3. Pattern Syntax
      1. Matching Literals
      2. Matching Named Variables
      3. Multiple Patterns
      4. Matching Ranges of Values with ..=
      5. Destructuring to Break Apart Values
      6. Ignoring Values in a Pattern
      7. Extra Conditionals with Match Guards
      8. @ Bindings
    4. Summary
  26. Chapter 19: Advanced Features
    1. Unsafe Rust
      1. Unsafe Superpowers
      2. Dereferencing a Raw Pointer
      3. Calling an Unsafe Function or Method
      4. Accessing or Modifying a Mutable Static Variable
      5. Implementing an Unsafe Trait
      6. Accessing Fields of a Union
      7. When to Use Unsafe Code
    2. Advanced Traits
      1. Associated Types
      2. Default Generic Type Parameters and Operator Overloading
      3. Disambiguating Between Methods with the Same Name
      4. Using Supertraits
      5. Using the Newtype Pattern to Implement External Traits
    3. Advanced Types
      1. Using the Newtype Pattern for Type Safety and Abstraction
      2. Creating Type Synonyms with Type Aliases
      3. The Never Type That Never Returns
      4. Dynamically Sized Types and the Sized Trait
    4. Advanced Functions and Closures
      1. Function Pointers
      2. Returning Closures
    5. Macros
      1. The Difference Between Macros and Functions
      2. Declarative Macros with macro_rules! for General Metaprogramming
      3. Procedural Macros for Generating Code from Attributes
      4. How to Write a Custom derive Macro
      5. Attribute-Like Macros
      6. Function-Like Macros
    6. Summary
  27. Chapter 20: Final Project: Building a Multithreaded Web Server
    1. Building a Single-Threaded Web Server
      1. Listening to the TCP Connection
      2. Reading the Request
      3. A Closer Look at an HTTP Request
      4. Writing a Response
      5. Returning Real HTML
      6. Validating the Request and Selectively Responding
      7. A Touch of Refactoring
    2. Turning Our Single-Threaded Server into a Multithreaded Server
      1. Simulating a Slow Request
      2. Improving Throughput with a Thread Pool
    3. Graceful Shutdown and Cleanup
      1. Implementing the Drop Trait on ThreadPool
      2. Signaling to the Threads to Stop Listening for Jobs
    4. Summary
  28. Appendix A: Keywords
    1. Keywords Currently in Use
    2. Keywords Reserved for Future Use
    3. Raw Identifiers
  29. Appendix B: Operators and Symbols
    1. Operators
    2. Non-operator Symbols
  30. Appendix C: Derivable Traits
    1. Debug for Programmer Output
    2. PartialEq and Eq for Equality Comparisons
    3. PartialOrd and Ord for Ordering Comparisons
    4. Clone and Copy for Duplicating Values
    5. Hash for Mapping a Value to a Value of Fixed Size
    6. Default for Default Values
  31. Appendix D: Useful Development Tools
    1. Automatic Formatting with rustfmt
    2. Fix Your Code with rustfix
    3. More Lints with Clippy
    4. IDE Integration Using rust-analyzer
  32. Appendix E: Editions
  33. Index

Product information

  • Title: The Rust Programming Language, 2nd Edition
  • Author(s): Steve Klabnik, Carol Nichols
  • Release date: February 2023
  • Publisher(s): No Starch Press
  • ISBN: 9781098156800