Programming Rust

Book description

Rust is a new systems programming language that combines the performance and low-level control of C and C++ with memory safety and thread safety. Rust’s modern, flexible types ensure your program is free of null pointer dereferences, double frees, dangling pointers, and similar bugs, all at compile time, without runtime overhead. In multi-threaded code, Rust catches data races at compile time, making concurrency much easier to use.

Written by two experienced systems programmers, this book explains how Rust manages to bridge the gap between performance and safety, and how you can take advantage of it. Topics include:

  • How Rust represents values in memory (with diagrams)
  • Complete explanations of ownership, moves, borrows, and lifetimes
  • Cargo, rustdoc, unit tests, and how to publish your code on crates.io, Rust’s public package repository
  • High-level features like generic code, closures, collections, and iterators that make Rust productive and flexible
  • Concurrency in Rust: threads, mutexes, channels, and atomics, all much safer to use than in C or C++
  • Unsafe code, and how to preserve the integrity of ordinary code that uses it
  • Extended examples illustrating how pieces of the language fit together

Publisher resources

View/Submit Errata

Table of contents

  1. Preface
    1. Who Should Read This Book
    2. Why We Wrote This Book
    3. Navigating This Book
    4. Conventions Used in This Book
    5. Using Code Examples
    6. O’Reilly Safari
    7. How to Contact Us
    8. Acknowledgments
  2. 1. Why Rust?
    1. Type Safety
  3. 2. A Tour of Rust
    1. Downloading and Installing Rust
    2. A Simple Function
    3. Writing and Running Unit Tests
    4. Handling Command-Line Arguments
    5. A Simple Web Server
    6. Concurrency
      1. What the Mandelbrot Set Actually Is
      2. Parsing Pair Command-Line Arguments
      3. Mapping from Pixels to Complex Numbers
      4. Plotting the Set
      5. Writing Image Files
      6. A Concurrent Mandelbrot Program
      7. Running the Mandelbrot Plotter
      8. Safety Is Invisible
  4. 3. Basic Types
    1. Machine Types
      1. Integer Types
      2. Floating-Point Types
      3. The bool Type
      4. Characters
    2. Tuples
    3. Pointer Types
      1. References
      2. Boxes
      3. Raw Pointers
    4. Arrays, Vectors, and Slices
      1. Arrays
      2. Vectors
      3. Slices
    5. String Types
      1. String Literals
      2. Byte Strings
      3. Strings in Memory
      4. String
      5. Using Strings
      6. Other String-Like Types
    6. Beyond the Basics
  5. 4. Ownership
    1. Ownership
    2. Moves
      1. More Operations That Move
      2. Moves and Control Flow
      3. Moves and Indexed Content
    3. Copy Types: The Exception to Moves
    4. Rc and Arc: Shared Ownership
  6. 5. References
    1. References as Values
      1. Rust References Versus C++ References
      2. Assigning References
      3. References to References
      4. Comparing References
      5. References Are Never Null
      6. Borrowing References to Arbitrary Expressions
      7. References to Slices and Trait Objects
    2. Reference Safety
      1. Borrowing a Local Variable
      2. Receiving References as Parameters
      3. Passing References as Arguments
      4. Returning References
      5. Structs Containing References
      6. Distinct Lifetime Parameters
      7. Omitting Lifetime Parameters
    3. Sharing Versus Mutation
    4. Taking Arms Against a Sea of Objects
  7. 6. Expressions
    1. An Expression Language
    2. Blocks and Semicolons
    3. Declarations
    4. if and match
      1. if let
    5. Loops
    6. return Expressions
    7. Why Rust Has loop
    8. Function and Method Calls
    9. Fields and Elements
    10. Reference Operators
    11. Arithmetic, Bitwise, Comparison, and Logical Operators
    12. Assignment
    13. Type Casts
    14. Closures
    15. Precedence and Associativity
    16. Onward
  8. 7. Error Handling
    1. Panic
      1. Unwinding
      2. Aborting
    2. Result
      1. Catching Errors
      2. Result Type Aliases
      3. Printing Errors
      4. Propagating Errors
      5. Working with Multiple Error Types
      6. Dealing with Errors That “Can’t Happen”
      7. Ignoring Errors
      8. Handling Errors in main()
      9. Declaring a Custom Error Type
      10. Why Results?
  9. 8. Crates and Modules
    1. Crates
      1. Build Profiles
    2. Modules
      1. Modules in Separate Files
      2. Paths and Imports
      3. The Standard Prelude
      4. Items, the Building Blocks of Rust
    3. Turning a Program into a Library
    4. The src/bin Directory
    5. Attributes
    6. Tests and Documentation
      1. Integration Tests
      2. Documentation
      3. Doc-Tests
    7. Specifying Dependencies
      1. Versions
      2. Cargo.lock
    8. Publishing Crates to crates.io
    9. Workspaces
    10. More Nice Things
  10. 9. Structs
    1. Named-Field Structs
    2. Tuple-Like Structs
    3. Unit-Like Structs
    4. Struct Layout
    5. Defining Methods with impl
    6. Generic Structs
    7. Structs with Lifetime Parameters
    8. Deriving Common Traits for Struct Types
    9. Interior Mutability
  11. 10. Enums and Patterns
    1. Enums
      1. Enums with Data
      2. Enums in Memory
      3. Rich Data Structures Using Enums
      4. Generic Enums
    2. Patterns
      1. Literals, Variables, and Wildcards in Patterns
      2. Tuple and Struct Patterns
      3. Reference Patterns
      4. Matching Multiple Possibilities
      5. Pattern Guards
      6. @ patterns
      7. Where Patterns Are Allowed
      8. Populating a Binary Tree
    3. The Big Picture
  12. 11. Traits and Generics
    1. Using Traits
      1. Trait Objects
      2. Trait Object Layout
      3. Generic Functions
      4. Which to Use
    2. Defining and Implementing Traits
      1. Default Methods
      2. Traits and Other People’s Types
      3. Self in Traits
      4. Subtraits
      5. Static Methods
    3. Fully Qualified Method Calls
    4. Traits That Define Relationships Between Types
      1. Associated Types (or How Iterators Work)
      2. Generic Traits (or How Operator Overloading Works)
      3. Buddy Traits (or How rand::random() Works)
    5. Reverse-Engineering Bounds
    6. Conclusion
  13. 12. Operator Overloading
    1. Arithmetic and Bitwise Operators
      1. Unary Operators
      2. Binary Operators
      3. Compound Assignment Operators
    2. Equality Tests
    3. Ordered Comparisons
    4. Index and IndexMut
    5. Other Operators
  14. 13. Utility Traits
    1. Drop
    2. Sized
    3. Clone
    4. Copy
    5. Deref and DerefMut
    6. Default
    7. AsRef and AsMut
    8. Borrow and BorrowMut
    9. From and Into
    10. ToOwned
    11. Borrow and ToOwned at Work: The Humble Cow
  15. 14. Closures
    1. Capturing Variables
      1. Closures That Borrow
      2. Closures That Steal
    2. Function and Closure Types
    3. Closure Performance
    4. Closures and Safety
      1. Closures That Kill
      2. FnOnce
      3. FnMut
    5. Callbacks
    6. Using Closures Effectively
  16. 15. Iterators
    1. The Iterator and IntoIterator Traits
    2. Creating Iterators
      1. iter and iter_mut Methods
      2. IntoIterator Implementations
      3. drain Methods
      4. Other Iterator Sources
    3. Iterator Adapters
      1. map and filter
      2. filter_map and flat_map
      3. scan
      4. take and take_while
      5. skip and skip_while
      6. peekable
      7. fuse
      8. Reversible Iterators and rev
      9. inspect
      10. chain
      11. enumerate
      12. zip
      13. by_ref
      14. cloned
      15. cycle
    4. Consuming Iterators
      1. Simple Accumulation: count, sum, product
      2. max, min
      3. max_by, min_by
      4. max_by_key, min_by_key
      5. Comparing Item Sequences
      6. any and all
      7. position, rposition, and ExactSizeIterator
      8. fold
      9. nth
      10. last
      11. find
      12. Building Collections: collect and FromIterator
      13. The Extend Trait
      14. partition
    5. Implementing Your Own Iterators
  17. 16. Collections
    1. Overview
    2. Vec<T>
      1. Accessing Elements
      2. Iteration
      3. Growing and Shrinking Vectors
      4. Joining
      5. Splitting
      6. Swapping
      7. Sorting and Searching
      8. Comparing Slices
      9. Random Elements
      10. Rust Rules Out Invalidation Errors
    3. VecDeque<T>
    4. LinkedList<T>
    5. BinaryHeap<T>
    6. HashMap<K, V> and BTreeMap<K, V>
      1. Entries
      2. Map Iteration
    7. HashSet<T> and BTreeSet<T>
      1. Set Iteration
      2. When Equal Values Are Different
      3. Whole-Set Operations
    8. Hashing
      1. Using a Custom Hashing Algorithm
    9. Beyond the Standard Collections
  18. 17. Strings and Text
    1. Some Unicode Background
      1. ASCII, Latin-1, and Unicode
      2. UTF-8
      3. Text Directionality
    2. Characters (char)
      1. Classifying Characters
      2. Handling Digits
      3. Case Conversion for Characters
      4. Conversions to and from Integers
    3. String and str
      1. Creating String Values
      2. Simple Inspection
      3. Appending and Inserting Text
      4. Removing Text
      5. Conventions for Searching and Iterating
      6. Patterns for Searching Text
      7. Searching and Replacing
      8. Iterating over Text
      9. Trimming
      10. Case Conversion for Strings
      11. Parsing Other Types from Strings
      12. Converting Other Types to Strings
      13. Borrowing as Other Text-Like Types
      14. Accessing Text as UTF-8
      15. Producing Text from UTF-8 Data
      16. Putting Off Allocation
      17. Strings as Generic Collections
    4. Formatting Values
      1. Formatting Text Values
      2. Formatting Numbers
      3. Formatting Other Types
      4. Formatting Values for Debugging
      5. Formatting Pointers for Debugging
      6. Referring to Arguments by Index or Name
      7. Dynamic Widths and Precisions
      8. Formatting Your Own Types
      9. Using the Formatting Language in Your Own Code
    5. Regular Expressions
      1. Basic Regex Use
      2. Building Regex Values Lazily
    6. Normalization
      1. Normalization Forms
      2. The unicode-normalization Crate
  19. 18. Input and Output
    1. Readers and Writers
      1. Readers
      2. Buffered Readers
      3. Reading Lines
      4. Collecting Lines
      5. Writers
      6. Files
      7. Seeking
      8. Other Reader and Writer Types
      9. Binary Data, Compression, and Serialization
    2. Files and Directories
      1. OsStr and Path
      2. Path and PathBuf Methods
      3. Filesystem Access Functions
      4. Reading Directories
      5. Platform-Specific Features
    3. Networking
  20. 19. Concurrency
    1. Fork-Join Parallelism
      1. spawn and join
      2. Error Handling Across Threads
      3. Sharing Immutable Data Across Threads
      4. Rayon
      5. Revisiting the Mandelbrot Set
    2. Channels
      1. Sending Values
      2. Receiving Values
      3. Running the Pipeline
      4. Channel Features and Performance
      5. Thread Safety: Send and Sync
      6. Piping Almost Any Iterator to a Channel
      7. Beyond Pipelines
    3. Shared Mutable State
      1. What Is a Mutex?
      2. Mutex<T>
      3. mut and Mutex
      4. Why Mutexes Are Not Always a Good Idea
      5. Deadlock
      6. Poisoned Mutexes
      7. Multi-Consumer Channels Using Mutexes
      8. Read/Write Locks (RwLock<T>)
      9. Condition Variables (Condvar)
      10. Atomics
      11. Global Variables
    4. What Hacking Concurrent Code in Rust Is Like
  21. 20. Macros
    1. Macro Basics
      1. Basics of Macro Expansion
      2. Unintended Consequences
      3. Repetition
    2. Built-In Macros
    3. Debugging Macros
    4. The json! Macro
      1. Fragment Types
      2. Recursion in Macros
      3. Using Traits with Macros
      4. Scoping and Hygiene
      5. Importing and Exporting Macros
    5. Avoiding Syntax Errors During Matching
    6. Beyond macro_rules!
  22. 21. Unsafe Code
    1. Unsafe from What?
    2. Unsafe Blocks
      1. Example: An Efficient ASCII String Type
    3. Unsafe Functions
    4. Unsafe Block or Unsafe Function?
    5. Undefined Behavior
    6. Unsafe Traits
    7. Raw Pointers
      1. Dereferencing Raw Pointers Safely
      2. Example: RefWithFlag
      3. Nullable Pointers
      4. Type Sizes and Alignments
      5. Pointer Arithmetic
      6. Moving into and out of Memory
      7. Example: GapBuffer
      8. Panic Safety in Unsafe Code
    8. Foreign Functions: Calling C and C++ from Rust
      1. Finding Common Data Representations
      2. Declaring Foreign Functions and Variables
      3. Using Functions from Libraries
      4. A Raw Interface to libgit2
      5. A Safe Interface to libgit2
    9. Conclusion
  23. Index

Product information

  • Title: Programming Rust
  • Author(s): Jim Blandy, Jason Orendorff
  • Release date: December 2017
  • Publisher(s): O'Reilly Media, Inc.
  • ISBN: 9781491927281