/ learning / rust / notes.org
notes.org
   1  #+title: The Rust Programming Language
   2  
   3  /by Steve labnik, carol Nichols, and Chris Krycho, with contributions from the Rust Community/
   4  
   5  This version of the text assumes you’re using Rust 1.90.0 (released 2025-09-18) or later with =edition = "2024"= in the /Cargo.toml/ file of all projects to configure them to use Rust 2024 Edition idioms. See the [[*Installation][“Installation” section of Chapter 1]] for instructions on installing or updating Rust, and see [[*E - Editions][Appendix E]] for information on editions.
   6  
   7  The HTML format is available online at https://doc.rust-lang.org/stable/book/ and offline with installations of Rust made with =rustup=; run =rustup doc --book= to open.
   8  
   9  Several community [[*F - Translations of the Book][translations]] are also available.
  10  
  11  This text is available in [[https://nostarch.com/rust-programming-language-3e][paperback and ebook format from No Starch Press]].
  12  
  13  #+begin_quote
  14  🚨 Want a more interactive learning experience?
  15  
  16  Try the Rust Book with quizzes, highlighting, and more:
  17  https://rust-book.cs.brown.edu
  18  #+end_quote
  19  
  20  - *Foreward*
  21  
  22    The Rust programming language has come a long way in a few short years, from its creation and incubation by a small and nascent community of enthusiasts, to becoming one of the most loved and in-demand programming languages in the world. Looking back, it was inevitable that the power and promise of Rust would turn heads and gain a foothold in systems programming. What was not inevitable was the global growth in interest and innovation that permeated through open source communities and catalyzed wide-scale adoption across industries.
  23  
  24    At this point in time, it is easy to point to the wonderful features that Rust has to offer to explain this explosion in interest and adoption. Who doesn’t want memory safety, and fast performance, and a friendly compiler, and great tooling, among a host of other wonderful features? The Rust language you see today combines years of research in systems programming with the practical wisdom of a vibrant and passionate community. This language was designed with purpose and crafted with care, offering developers a tool that makes it easier to write safe, fast, and reliable code.
  25  
  26    But what makes Rust truly special is its roots in empowering you, the user, to achieve your goals. This is a language that wants you to succeed, and the principle of empowerment runs through the core of the community that builds, maintains, and advocates for this language. Since the previous edition of this definitive text, Rust has further developed into a truly global and trusted language. The Rust Project is now robustly supported by the Rust Foundation, which also invests in key initiatives to ensure that Rust is secure, stable, and sustainable.
  27  
  28    This edition of The Rust Programming Language is a comprehensive update, reflecting the language’s evolution over the years and providing valuable new information. But it is not just a guide to syntax and libraries—it’s an invitation to join a community that values quality, performance, and thoughtful design. Whether you’re a seasoned developer looking to explore Rust for the first time or an experienced Rustacean looking to refine your skills, this edition offers something for everyone.
  29  
  30    The Rust journey has been one of collaboration, learning, and iteration. The growth of the language and its ecosystem is a direct reflection of the vibrant, diverse community behind it. The contributions of thousands of developers, from core language designers to casual contributors, are what make Rust such a unique and powerful tool. By picking up this book, you’re not just learning a new programming language—you’re joining a movement to make software better, safer, and more enjoyable to work with.
  31  
  32    Welcome to the Rust community!
  33  
  34     * Bec Rumbul, Executive Director of the Rust Foundation
  35  
  36  - *Introduction*
  37  
  38  #+begin_quote
  39  Note: This edition of the book is the same as [[https://nostarch.com/rust-programming-language-3e][The Rust Programming Language]] available in print and ebook format from [[https://nostarch.com][No Starch Press]].
  40  #+end_quote
  41  
  42  Welcome to /The Rust Programming Language/, an introductory book about Rust. The Rust programming language helps you write faster, more reliable software. High-level ergonomics and low-level control are often at odds in programming language design; Rust challenges that conflict. Through balancing powerful technical capacity and a great developer experience, Rust gives you the option to control low-level details (such as memory usage) without all the hassle traditionally associated with such control.
  43  
  44  *Who Rust Is For*
  45  
  46  Rust is ideal for many people for a variety of reasons. Let’s look at a few of the most important groups.
  47  
  48  *Teams of Developers*
  49  
  50  Rust is proving to be a productive tool for collaborating among large teams of developers with varying levels of systems programming knowledge. Low-level code is prone to various subtle bugs, which in most other languages can only be caught through extensive testing and careful code review by experienced developers. In Rust, the compiler plays a gatekeeper role by refusing to compile code with these elusive bugs, including concurrency bugs. By working alongside the compiler, the team can spend its time focusing on the program’s logic rather than chasing down bugs.
  51  
  52  Rust also brings contemporary developer tools to the systems programming world:
  53  
  54   * Cargo, the included dependency manager and build tool, makes adding, compiling, and managing dependencies painless and consistent across the Rust ecosystem.
  55   * The =rustfmt= formatting tool ensures a consistent coding style across developers.
  56   * The Rust Language Server powers integrated development environment (IDE) integration for code completion and inline error messages.
  57  
  58  By using these and other tools in the Rust ecosystem, developers can be productive while writing systems-level code.
  59  
  60  *Students*
  61  
  62  Rust is for students and those who are interested in learning about systems concepts. Using Rust, many people have learned about topics like operating systems development. The community is very welcoming and happy to answer students’ questions. Through efforts such as this book, the Rust teams want to make systems concepts more accessible to more people, especially those new to programming.
  63  
  64  *Companies*
  65  
  66  Hundreds of companies, large and small, use Rust in production for a variety of tasks, including command line tools, web services, DevOps tooling, embedded devices, audio and video analysis and transcoding, cryptocurrencies, bioinformatics, search engines, Internet of Things applications, machine learning, and even major parts of the Firefox web browser.
  67  
  68  *Open Source Developers*
  69  
  70  Rust is for people who want to build the Rust programming language, community, developer tools, and libraries. We’d love to have you contribute to the Rust language.
  71  
  72  *People Who Value Speed and Stability*
  73  
  74  Rust is for people who crave speed and stability in a language. By speed, we mean both how quickly Rust code can run and the speed at which Rust lets you write programs. The Rust compiler’s checks ensure stability through feature additions and refactoring. This is in contrast to the brittle legacy code in languages without these checks, which developers are often afraid to modify. By striving for zero-cost abstractions—higher-level features that compile to lower-level code as fast as code written manually—Rust endeavors to make safe code be fast code as well.
  75  
  76  The Rust language hopes to support many other users as well; those mentioned here are merely some of the biggest stakeholders. Overall, Rust’s greatest ambition is to eliminate the trade-offs that programmers have accepted for decades by providing safety and productivity, speed and ergonomics. Give Rust a try, and see if its choices work for you.
  77  
  78  *Who This Book Is For*
  79  
  80  This book assumes that you’ve written code in another programming language, but it doesn’t make any assumptions about which one. We’ve tried to make the material broadly accessible to those from a wide variety of programming backgrounds. We don’t spend a lot of time talking about what programming is or how to think about it. If you’re entirely new to programming, you would be better served by reading a book that specifically provides an introduction to programming.
  81  
  82  *How to Use This Book*
  83  
  84  In general, this book assumes that you’re reading it in sequence from front to back. Later chapters build on concepts in earlier chapters, and earlier chapters might not delve into details on a particular topic but will revisit the topic in a later chapter.
  85  
  86  You’ll find two kinds of chapters in this book: concept chapters and project chapters. In concept chapters, you’ll learn about an aspect of Rust. In project chapters, we’ll build small programs together, applying what you’ve learned so far. Chapter 2, Chapter 12, and Chapter 21 are project chapters; the rest are concept chapters.
  87  
  88  [[*Getting Started][Chapter 1]] explains how to install Rust, how to write a “Hello, world!” program, and how to use Cargo, Rust’s package manager and build tool. [[*Programming a Guessing Game][Chapter 2]] is a hands-on introduction to writing a program in Rust, having you build up a number-guessing game. Here, we cover concepts at a high level, and later chapters will provide additional detail. If you want to get your hands dirty right away, Chapter 2 is the place for that. If you’re a particularly meticulous learner who prefers to learn every detail before moving on to the next, you might want to skip Chapter 2 and go straight to [[* Common Programming Concepts][Chapter 3]], which covers Rust features that are similar to those of other programming languages; then, you can return to Chapter 2 when you’d like to work on a project applying the details you’ve learned.
  89  
  90  In [[* Understanding Ownership][Chapter 4]], you’ll learn about Rust’s ownership system. [[*Using Structs to Structure Related Data][Chapter 5]] discusses structs and methods. [[*Enums and Pattern Matching][Chapter 6]] covers enums, =match= expressions, and the =if let= and =let...else= control flow constructs. You’ll use structs and enums to make custom types.
  91  
  92  In [[Packages, Crates, and Modules][Chapter 7]], you’ll learn about Rust’s module system and about privacy rules for organizing your code and its public application programming interface (API). [[*Common Collections][Chapter 8]] discusses some common collection data structures that the standard library provides: vectors, strings, and hash maps. [[*Error Handling][Chapter 9]] explores Rust’s error-handling philosophy and techniques.
  93  
  94  [[Generic Types, Traits, and Lifetimes][Chapter 10]] digs into generics, traits, and lifetimes, which give you the power to define code that applies to multiple types. [[*Writing Automated Tests][Chapter 11]] is all about testing, which even with Rust’s safety guarantees is necessary to ensure that your program’s logic is correct. In [[*An I/O Project: Building a Command Line Program][Chapter 12]], we’ll build our own implementation of a subset of functionality from the grep command line tool that searches for text within files. For this, we’ll use many of the concepts we discussed in the previous chapters.
  95  
  96  [[*Functional Language Features: Iterators and Closures][Chapter 13]] explores closures and iterators: features of Rust that come from functional programming languages. In [[*More about Cargo and Crates.io][Chapter 14]], we’ll examine Cargo in more depth and talk about best practices for sharing your libraries with others. [[*Smart Pointers][Chapter 15]] discusses smart pointers that the standard library provides and the traits that enable their functionality.
  97  
  98  In [[*Fearless Concurrency][Chapter 16]], we’ll walk through different models of concurrent programming and talk about how Rust helps you program in multiple threads fearlessly. In [[*Fundamentals of Asynchronous Programming: Async, Await, Futures, and Streams][Chapter 17]], we build on that by exploring Rust’s async and await syntax, along with tasks, futures, and streams, and the lightweight concurrency model they enable.
  99  
 100  [[*Object Oriented Programming Features][Chapter 18]] looks at how Rust idioms compare to object-oriented programming principles you might be familiar with. [[*Patterns and Matching][Chapter 19]] is a reference on patterns and pattern matching, which are powerful ways of expressing ideas throughout Rust programs. [[*Advanced Features][Chapter 20]] contains a smorgasbord of advanced topics of interest, including unsafe Rust, macros, and more about lifetimes, traits, types, functions, and closures.
 101  
 102  In [[Final Project: Building a Multithreaded Web Server][Chapter 21]], we’ll complete a project in which we’ll implement a low-level multithreaded web server!
 103  
 104  Finally, some appendixes contain useful information about the language in a more reference-like format. [[*A - Keywords][Appendix A]] covers Rust’s keywords, [[*B - Operators and Symbols][Appendix B]] covers Rust’s operators and symbols, [[*C - Derivable Traits][Appendix C]] covers derivable traits provided by the standard library, [[*Useful Development Tools][Appendix D]] covers some useful development tools, and [[*E - Editions][Appendix E]] explains Rust editions. In [[*F - Translations of the Book][Appendix F]], you can find translations of the book, and in [[*G - How Rust is Made and "Nightly Rust"][Appendix G]] we’ll cover how Rust is made and what nightly Rust is.
 105  
 106  There is no wrong way to read this book: If you want to skip ahead, go for it! You might have to jump back to earlier chapters if you experience any confusion. But do whatever works for you.
 107  
 108  
 109  An important part of the process of learning Rust is learning how to read the error messages the compiler displays: These will guide you toward working code. As such, we’ll provide many examples that don’t compile along with the error message the compiler will show you in each situation. Know that if you enter and run a random example, it may not compile! Make sure you read the surrounding text to see whether the example you’re trying to run is meant to error. In most situations, we’ll lead you to the correct version of any code that doesn’t compile. Ferris will also help you distinguish code that isn’t meant to work:
 110  
 111  | *Ferris* | *Meaning*                                          |
 112  |--------+--------------------------------------------------|
 113  |        | This code does not compile!                      |
 114  |        | This code panics!                                |
 115  |        | This code does not produce the desired behavior. |
 116  
 117  *Source Code*
 118  
 119  The source files from which this book is generated can be found on [[https://github.com/rust-lang/book/tree/main/src][GitHub]].
 120  
 121  * Getting Started
 122  
 123  Let’s start your Rust journey! There’s a lot to learn, but every journey starts somewhere. In this chapter, we’ll discuss:
 124  
 125   * Installing Rust on Linux, macOS, and Windows
 126   * Writing a program that prints =Hello, world!=
 127   * Using =cargo=, Rust’s package manager and build system
 128  
 129  ** Installation
 130  ** Hello, World!
 131  ** Hello, Cargo!
 132  
 133  * Programming a Guessing Game
 134  
 135  #+BEGIN_SRC toml
 136  [package]
 137  name = "guessing_game"
 138  version = "0.1.0"
 139  edition = "2024"
 140  # edition.workspace = true
 141  
 142  [dependencies]
 143  rand = "0.9.0"
 144  
 145  [workspace]
 146  #+END_SRC
 147  
 148  #+BEGIN_SRC rust
 149  use std::cmp::Ordering;
 150  use std::io;
 151  use rand::Rng;
 152  
 153  fn main() {
 154    println!("Guess the number!");
 155  
 156    let secret_number =
 157      rand::thread_rng().gen_range(1..=100);
 158  
 159    // println!("The secret number is: {secret_number}");
 160  
 161    loop  {
 162    println!("Please input your guess.");
 163  
 164    let mut guess = String::new();
 165  
 166    io::stdin()
 167      .read_line(&mut guess)
 168      .expect("Failed to read line");
 169  
 170    let guess: u32 = match guess
 171      .trim()
 172      .parse(){
 173        Ok(num) => num,
 174        Err(_) => continue
 175      };
 176  
 177    println!("You guessed: {guess}");
 178  
 179    match guess.cmp(&secret_number){
 180      Ordering::Less => println!("Too small!"),
 181      Ordering::Greater => println!("Too big!"),
 182      Ordering::Equal => {
 183        println!("You win!");
 184        break;
 185    }
 186    }
 187    }
 188  }
 189  #+END_SRC
 190  * Common Programming Concepts
 191  ** Variables and Mutability
 192  
 193  #+BEGIN_SRC rust
 194  use std::io;
 195  
 196  #[allow(unused)]
 197  fn main() {
 198      let x = 5;
 199  
 200      let x = x + 1;
 201  
 202      {
 203          let x = x * 2;
 204          println!("The value of x in the inner scope is: {x}");
 205      }
 206  
 207      println!("The value of x is: {x}");
 208  
 209      let spaces = "   ";
 210      let spaces = spaces.len();
 211      println!("Length of spaces is: {spaces}");
 212  
 213      let guess: u32 = "42".parse().expect("Not a number!");
 214  
 215      let x = 2.0; // f64
 216      let y: f32 = 3.0; // f32
 217  
 218      // addition
 219      let sum = 5 + 10;
 220  
 221      // subtraction
 222      let difference = 95.5 - 4.3;
 223  
 224      // multiplication
 225      let product = 4 * 30;
 226  
 227      // division
 228      let quotient = 56.7 / 32.2;
 229      let truncated = -5 / 3; // Results in -1
 230  
 231      // remainder
 232      let remainder = 43 % 5;
 233  
 234      let t = true;
 235      let f: bool = false; // with explicit type annotation
 236  
 237      let c = 'z';
 238      let z: char = 'Z'; // with explicit type annotation
 239      let heart_eyed_cat = '😻';
 240  
 241      let tup: (i32, f64, u8) = (500, 6.4, 1);
 242      println!("{:?}", tup);
 243  
 244      let tup = (500, 6.4, 1);
 245  
 246      let (x, y, z) = tup;
 247  
 248      println!("The value of y is: {y}");
 249  
 250      let x: (i32, f64, u8) = (500, 6.4, 1);
 251  
 252      let five_hundred = x.0;
 253  
 254      let six_point_four = x.1;
 255  
 256      let one = x.2;
 257  
 258      let a = [1, 2, 3, 4, 5];
 259  
 260      let months = [
 261          "January",
 262          "February",
 263          "March",
 264          "April",
 265          "May",
 266          "June",
 267          "July",
 268          "August",
 269          "September",
 270          "October",
 271          "November",
 272          "December",
 273      ];
 274  
 275      let a: [i32; 5] = [1, 2, 3, 4, 5];
 276  
 277      let a = [3; 5]; // 3, 3, 3, 3, 3
 278  
 279      let first = a[0];
 280      let second = a[1];
 281  
 282      // invalid array element access
 283      let a = [1, 2, 3, 4, 5];
 284  
 285      println!("Please enter an array index.");
 286  
 287      let mut index = String::new();
 288  
 289      io::stdin()
 290          .read_line(&mut index)
 291          .expect("Failed to read line");
 292  
 293      let index: usize = index
 294          .trim()
 295          .parse()
 296          .expect("Index entered was not a number");
 297  
 298      let element = a[index];
 299  
 300      println!("The value of the element at index {index} is: {element}");
 301  #+END_SRC
 302  
 303  ** Functions
 304  
 305  #+BEGIN_SRC rust
 306  fn main() {
 307      println!("Hello, world!");
 308  
 309      another_function();
 310      print_labeled_measurement(5, 'h');
 311      an_expression();
 312      // statement_to_another_variable_wont_compile();
 313      statement_to_expression();
 314  
 315      let x = five();
 316  
 317      println!("The value of x is: {x}");
 318  
 319      let x = plus_one(5);
 320  
 321      println!("The value of x is: {x}");
 322  }
 323  
 324  fn another_function() {
 325      println!("Another function.");
 326  }
 327  
 328  fn print_labeled_measurement(value: i32, unit_label: char) {
 329      println!("The measurement is: {value}{unit_label}")
 330  }
 331  
 332  fn an_expression() {
 333      let y = 6;
 334  }
 335  
 336  // fn statement_to_another_variable_wont_compile(){
 337  //   let x = (let y =6);
 338  // }
 339  
 340  fn statement_to_expression() {
 341      let y = {
 342          let x = 3;
 343          x + 1
 344          // expressions don't include ending semicolons
 345          // adding a semicolor to the end of an expression turns it into a statement, which will not return a value
 346      };
 347  
 348      println!("The value of y is: {y}")
 349  }
 350  
 351  fn five() -> i32 {
 352      5
 353  }
 354  
 355  fn plus_one(x: i32) -> i32 {
 356      x + 1
 357  }
 358  #+END_SRC
 359  
 360  ** Comments
 361  
 362  #+BEGIN_SRC rust
 363    #![allow(unused)]
 364    fn main() {
 365        // hello, world
 366  
 367        // So we're doing something complicated here, long enough that we need
 368        // multiple lines of comments to do it! Whew! Hopefully, this comment will
 369        // explain what's going on.
 370  
 371        let lucky_number = 7; // I'm feeling lucky today
 372  
 373        // I'm feeling lucky today
 374        let another_lucky_number = 7;
 375    }
 376  #+END_SRC
 377  
 378  ** Control Flow
 379  
 380  #+BEGIN_SRC rust
 381    fn if_expressions() {
 382        let number = 3;
 383  
 384        if number < 5 {
 385            println!("condition was true");
 386        } else {
 387            println!("condition was false");
 388        }
 389  
 390        let number = 7;
 391  
 392        if number < 5 {
 393            println!("condition was true");
 394        } else {
 395            println!("condition was false");
 396        }
 397  
 398        let number = 3;
 399        if number != 0 {
 400            println!("number was something other than zero");
 401        }
 402    }
 403  
 404    fn handling_multiple_conditions_with_else_if() {
 405        let number = 6;
 406  
 407        if number % 4 == 0 {
 408            println!("number is divisible by 4");
 409        } else if number % 3 == 0 {
 410            println!("number is divisible by 3");
 411        } else if number % 2 == 0 {
 412            println!("number is divisible by 2");
 413        } else {
 414            println!("number is not divisible by 4, 3, or 2");
 415        }
 416    }
 417  
 418    fn using_if_in_a_let_statement() {
 419        let condition = true;
 420        let number = if condition { 5 } else { 6 };
 421  
 422        println!("The value of number is: {number}");
 423    }
 424  
 425    fn repetition_with_loops() {
 426        loop {
 427            println!("again!");
 428        }
 429    }
 430  
 431    fn returning_values_from_loops() {
 432        let mut counter = 0;
 433  
 434        let result = loop {
 435            counter += 1;
 436  
 437            if counter == 10 {
 438                break counter * 2;
 439            }
 440        };
 441  
 442        println!("The result is {result}")
 443    }
 444  
 445    fn loop_labels_to_disambiguate_between_multiple_loops() {
 446        let mut count = 0;
 447  
 448        'counting_up: loop {
 449            println!("count = {count}");
 450            let mut remaining = 10;
 451  
 452            loop {
 453                println!("remaining = {remaining}");
 454                if remaining == 9 {
 455                    break;
 456                }
 457                if count == 2 {
 458                    break 'counting_up;
 459                }
 460                remaining -= 1;
 461            }
 462            count += 1;
 463        }
 464        println!("End count = {count}");
 465    }
 466  
 467    fn conditional_loops_with_while() {
 468        let mut number = 3;
 469  
 470        while number != 0 {
 471            println!("{number}!");
 472            number -= 1;
 473        }
 474  
 475        println!("LIFTOFF!!!");
 476    }
 477  
 478    fn looping_through_a_collection_with_for() {
 479        let a = [10, 20, 30, 40, 50];
 480        let mut index = 0;
 481  
 482        while index < 5 {
 483            println!("the value is: {}", a[index]);
 484  
 485            index += 1;
 486        }
 487  
 488        // more concise with for loop
 489        for element in a {
 490            println!("the value is: {element}");
 491        }
 492    }
 493  
 494    fn convert_temperature_between_fahrenheit_and_celcius() {
 495        loop {
 496            println!("Enter any number.");
 497            let mut number = String::new();
 498  
 499            std::io::stdin()
 500                .read_line(&mut number)
 501                .expect("Failed to read line");
 502  
 503            let number: u32 = match number.trim().parse() {
 504                Ok(num) => num,
 505                Err(_) => continue,
 506            };
 507  
 508            let celcius = (number - 32) / (9 / 5);
 509            let fahrenheit = (celcius * (9 / 5)) + 32;
 510  
 511            println!("{number}°F -> {celcius}°C");
 512            println!("{number}°C -> {fahrenheit}°F");
 513            break;
 514        }
 515    }
 516  
 517    fn generate_nth_fibonacci_number() {
 518        loop {
 519            println!("Enter any number for n.");
 520            let mut number = String::new();
 521  
 522            std::io::stdin()
 523                .read_line(&mut number)
 524                .expect("Failed to read line");
 525  
 526            let number: u32 = match number.trim().parse() {
 527                Ok(num) => num,
 528                Err(_) => continue,
 529            };
 530  
 531            match number.cmp(&1) {
 532                std::cmp::Ordering::Less => println!("0"),
 533                std::cmp::Ordering::Equal => println!("1"),
 534                std::cmp::Ordering::Greater => {
 535                    println!("Fn = Fn-1 + Fn+2 for n>1");
 536                    println!("Example: 0,1,1,2,3,5,8,13,21");
 537                }
 538            }
 539            break;
 540        }
 541    }
 542  
 543    fn main() {
 544        // if_expressions();
 545        // handling_multiple_conditions_with_else_if();
 546        // using_if_in_a_let_statement();
 547        // repetition_with_loops();
 548        // returning_values_from_loops();
 549        // loop_labels_to_disambiguate_between_multiple_loops();
 550        // conditional_loops_with_while();
 551        // looping_through_a_collection_with_for();
 552        convert_temperature_between_fahrenheit_and_celcius();
 553        generate_nth_fibonacci_number();
 554    }
 555  #+END_SRC
 556  
 557  * Understanding Ownership
 558  ** What is Ownership?
 559  
 560        #+BEGIN_SRC rust
 561    fn variables_and_data_interacting_with_move() {
 562        // let x = 5;
 563        // let y = x;
 564  
 565        let s1 = String::from("hello");
 566        let s2 = s1.clone();
 567  
 568        println!("s1 = {s1}, s2 = {s2}");
 569        println!("{s1}, world!");
 570    }
 571  
 572    fn stack_only_data_copy() {
 573        let x = 5;
 574        let y = x;
 575  
 576        println!("x = {x}, y = {y}");
 577    }
 578  
 579    fn ownership_and_functions() {
 580        let s = String::from("hello"); // s comes into scope
 581        takes_ownership(s); // s's value moves into the function...
 582        // ... and so is no longer valid here
 583        let x = 5; // x comes into scope
 584        makes_copy(x); // Because i32 implements the Copy trait,
 585        // x does NOT move into the function,
 586        // so it's okay to use x afterward.
 587    } // Here, x goes out of scope, then s. However, because s's value was moved,
 588    // nothing special happens.
 589  
 590    fn takes_ownership(some_string: String) {
 591        // some_string comes into scope
 592        println!("{some_string}");
 593    } // Here, some_string goes out of scope and `drop` is called. The backing
 594    // memory is freed.
 595  
 596    fn makes_copy(some_integer: i32) {
 597        // some_integer comes into scope
 598        println!("{some_integer}")
 599    } // Here, some_integer goes out of scope. Nothing special happens.
 600  
 601    fn return_values_and_scope() {
 602        let s1 = gives_ownership(); // gives_ownership moves its return value into s1
 603        let s2 = String::from("hello"); // s2 comes into scope
 604        let s3 = takes_and_gives_back(s2); // s2 is moved into takes_and_gives_back, which also moves its return value into s3
 605    } // Here, s3 goes out of scope and is dropped. s2 ws moved, so nothing happens. s1 goes out of scope and is dropped.
 606  
 607    fn gives_ownership() -> String {
 608        // gives_ownership will move its return value into the function that calls it
 609        let some_string = String::from("yours"); //some_string comes into scope
 610        some_string // some_string is returned and moves out to the calling function
 611    }
 612  
 613    // This function takes a String and returns a String.
 614    fn takes_and_gives_back(a_string: String) -> String {
 615        // a_string comes into scope
 616        a_string // a_string is returned and moves out to the calling function
 617    }
 618  
 619    fn return_multiple_values_using_a_tuple() {
 620        let s1 = String::from("hello");
 621        let (s2, len) = calculate_length(s1);
 622        println!("The length of '{s2}' is {len}.")
 623    }
 624  
 625    fn calculate_length(s: String) -> (String, usize) {
 626        let length = s.len(); // len() returns the length of a String
 627        (s, length)
 628    }
 629  
 630    fn main() {
 631        // let s = "hello";
 632        // let mut s = String::from("hello");
 633        // s.push_str(", world!");
 634        // println!("{s}");
 635        // variables_and_data_interacting_with_move();
 636        return_values_and_scope();
 637        return_multiple_values_using_a_tuple();
 638    }
 639        #+END_SRC
 640  
 641  ** References and Borrowing
 642  
 643     BEGIN_SRC rust
 644      calculate_length(s: &String) -> usize {
 645       // s is a reference to a String
 646       s.len()
 647     // Here, s goes out of scope. But because s does not have ownership of what it refers to, the String is not dropped.
 648  
 649      fn borrowing_without_returning(){
 650        let s = String::from("hello");
 651        change(&s);
 652      }
 653  
 654      fn change(some_string: &String){
 655        some_string.push_str(", world");
 656      }
 657  
 658      mutable_references() {
 659       let mut s = String::from("hello");
 660       {
 661           let r1 = &mut s;
 662       } // r1 goes out of scope here, so we can make a new reference with no problems.
 663       let r2 = &mut s;
 664  
 665       let r1 = &s; // no problem
 666       let r2 = &s; // no problem
 667       // let r3 = &mut s; // BIG PROBLEM
 668  
 669       // println!("{r1}, {r2}, and {r3}");
 670  
 671  
 672      reference_scope() {
 673       let mut s = String::from("hello");
 674       let r1 = &s; // no problem
 675       let r2 = &s; // no problem
 676       println!("{r1} and {r2}");
 677       // Variables r1 and r2 will not be used after this point.
 678  
 679       let r3 = &mut s; // no problem
 680       println!("{r3}");
 681  
 682  
 683      dangling_references() {
 684       // let reference_to_string = dangle();
 685       let reference_to_string = no_dangle();
 686  
 687  
 688      fn dangle() -> &String { // dangle returns a reference to a String
 689        let s = String::from("hello"); // s is a new String
 690        &s // we return a reference to the String, s
 691      } // Here, s goes out of scope and is dropped, so its memory goes away.
 692      // Danger!
 693  
 694      no_dangle() -> String {
 695       let s = String::from("hello");
 696       s
 697  
 698  
 699      main() {
 700       let s1 = String::from("hello");
 701       let len = calculate_length(&s1);
 702       println!("The length of '{s1}' is {len}.");
 703  
 704       // borrowing_without_returning();
 705       mutable_references();
 706       reference_scope();
 707  
 708     END_SRC
 709  
 710  ** The Slice Type
 711  
 712  #+BEGIN_SRC rust
 713    fn main() {
 714        let mut s = String::from("hello world");
 715        let word = first_word(&s);
 716        // s.clear(); // error
 717        println!("the first word is: {word}");
 718  
 719        let my_string = String::from("hello world");
 720  
 721        // `first_word` works on slices of `String`s, whether partial or whole.
 722        let word = first_word(&my_string[0..6]);
 723        let word = first_word(&my_string[..]);
 724        // `first_word` also works on references to `String`s, which are equivalent
 725        // to whole slices of `String`s
 726        let word = first_word(&my_string);
 727  
 728        let my_string_literal = "hello world";
 729  
 730        // `first_word` works on slices of string literals, whether partial or whole.
 731        let word = first_word(&my_string_literal[0..6]);
 732        let word = first_word(&my_string_literal[..]);
 733  
 734        // Because string literals *are* string slices already,
 735        // this works too, without the slice syntax!
 736        let word = first_word(my_string_literal);
 737  
 738        let a = [1, 2, 3, 4, 5];
 739  
 740        let slice = &a[1..3];
 741        assert_eq!(slice, &[2, 3]);
 742    }
 743  
 744    fn first_word(s: &str) -> &str {
 745        let bytes = s.as_bytes();
 746  
 747        for (i, &item) in bytes.iter().enumerate() {
 748            if item == b' ' {
 749                return &s[0..i];
 750            }
 751        }
 752  
 753        &s[..]
 754    }
 755  #+END_SRC
 756  
 757  * Using Structs to Structure Related Data
 758  ** Defining and Instantiating Structs
 759  
 760  #+BEGIN_SRC rust
 761  struct User {
 762      active: bool,
 763      username: String,
 764      email: String,
 765      sign_in_count: u64,
 766  }
 767  
 768  fn build_user(email: String, username: String) -> User {
 769      User {
 770          active: true,
 771          username,
 772          email,
 773          sign_in_count: 1,
 774      }
 775  }
 776  
 777  fn creating_different_types_with_tuple_structs() {
 778      struct Color(i32, i32, i32);
 779      struct Point(i32, i32, i32);
 780  
 781      let black = Color(0, 0, 0);
 782      let origin = Point(0, 0, 0);
 783  }
 784  
 785  fn defining_unit_like_structs() {
 786      struct AlwaysEqual;
 787  
 788      let subject = AlwaysEqual;
 789  }
 790  
 791  fn main() {
 792      let mut user1 = User {
 793          active: true,
 794          username: String::from("someusername123"),
 795          email: String::from("someone@example.com"),
 796          sign_in_count: 1,
 797      };
 798  
 799      user1.email = String::from("anotheremail@example.com");
 800  
 801      // let user2 = User {
 802      //   active: user1.active,
 803      //   username: user1.username,
 804      //   email: String::from("another@example.com"),
 805      //   sign_in_count: user1.sign_in_count,
 806      // };
 807  
 808      let user2 = User {
 809          email: String::from("another@example.com"),
 810          ..user1
 811      };
 812  
 813      creating_different_types_with_tuple_structs();
 814      defining_unit_like_structs();
 815  }
 816  #+END_SRC
 817  
 818  ** An Example Program Using Structs
 819  
 820  #+BEGIN_SRC rust
 821  fn area(width: u32, height: u32) -> u32 {
 822      width * height
 823  }
 824  
 825  fn refactoring_with_tuples() {
 826      fn area(dimensions: (u32, u32)) -> u32 {
 827          dimensions.0 * dimensions.1
 828      }
 829  
 830      let rect1 = (30, 50);
 831  
 832      println!(
 833          "The area of the rectangle is {} square pixels.",
 834          area(rect1)
 835      )
 836  }
 837  
 838  fn refactoring_with_structs() {
 839      struct Rectangle {
 840          width: u32,
 841          height: u32,
 842      }
 843  
 844      fn area(rectangle: &Rectangle) -> u32 {
 845          rectangle.width * rectangle.height
 846      }
 847  
 848      let rect1 = Rectangle {
 849          width: 30,
 850          height: 50,
 851      };
 852  
 853      println!(
 854          "The area of the rectangle is {} square pixels.",
 855          area(&rect1)
 856      )
 857  }
 858  
 859  fn adding_functionality_with_derived_traits() {
 860      #[derive(Debug)]
 861      struct Rectangle {
 862          width: u32,
 863          height: u32,
 864      }
 865  
 866      let rect1 = Rectangle {
 867          width: 30,
 868          height: 50,
 869      };
 870  
 871      println!("rect1 is {rect1:?}");
 872      println!("rect1 is {rect1:#?}");
 873  
 874      let scale = 2;
 875      let rect1 = Rectangle {
 876          width: dbg!(30 * scale),
 877          height: 50,
 878      };
 879  
 880      dbg!(&rect1);
 881  }
 882  
 883  fn main() {
 884      let width1 = 30;
 885      let height1 = 50;
 886  
 887      println!(
 888          "The area of the rectangle is {} square pixels.",
 889          area(width1, height1)
 890      );
 891  
 892      refactoring_with_tuples();
 893      refactoring_with_structs();
 894      adding_functionality_with_derived_traits();
 895  }
 896  #+END_SRC
 897  
 898  ** Methods
 899  
 900  Methods are similar to functions: We declare them with the =fn= keyword and a name, they can have parameters and a return value, and they contain some code that's run whe the method is called from somewhere else. Unlike functions, methods are defined within the context of a struct (or an enum or a trait object, which we cover in Chapter 6 and Chapter 18, respectively), and their first parameter is always =self=, which represents the instance of the struct the method is being called on.
 901  
 902  *** Method Syntax
 903  
 904  Let's change the =area= function that has a =Rectangle= instance as a parameter and instead make an =area= method defined on the =Rectangle= struct, as shown in Listing 5-13.
 905  
 906  #+BEGIN_SRC rust
 907  #[derive(Debug)]
 908  struct Rectangle {
 909      width: u32,
 910      height: u32
 911  }
 912  
 913  impl Rectangle {
 914      fn area(&self) -> u32 {
 915          self.width * self.height
 916      }
 917  }
 918  
 919  fn main() {
 920      let rect1 = Rectangle {
 921          width: 30,
 922          height: 50
 923      };
 924  
 925      println!(
 926          "The area of the rectangle is {} square pixels.",
 927          rect1.area()
 928      );
 929  }
 930  #+END_SRC
 931  Listing 5-13: Defining an =area= method on the =Rectangle= struct
 932  
 933  To define the function within the context of =Rectangle=, we start an =impl= (implementation) block for =Rectangle=. Everything within this =impl= block will be associated with the =Rectangle= type. kthen, we move the =area= function within the =impl= curly brackets and change the first (and in this case, only) parameter to be =self= in the signature and everywhere within the body. In =main=, where we called the =area= function and passed =rect1= as an argument, we can instead use /method syntax/ to call the =area= method on our =Rectangle= instance. The method syntax goes after an instance: We add a dot followed by the method name, parentheses, and any arguments.
 934  
 935  In the signature for =area=, we use =&self= instead of =rectangle: &Rectangle=. the =&self= is actually showrt for =self: &Self=. Within an =impl= block, the type =Self= is an alias for the type that the =impl= block is for. Methods must have a parameter named =self= of type =Self= for their first parameter, so Rust lets you abbreviate this with only the name =self= in the first parameter spot. Note that we still need to use the =&= in front of the =self= shorthand to indicate that this method borrows the =Self= instance, just as we did in =rectangle: &Rectangle=. Methods can take ownership of =self=, borrow =self= immutably, as we've done here, or borrow =self= mutably, just as they can any other parameter.
 936  
 937  #+BEGIN_SRC rust
 938  #[derive(Debug)]
 939  struct Rectangle {
 940      width: u32,
 941      height: u32
 942  }
 943  
 944  impl Rectangle {
 945      fn width(&self) -> bool{
 946          self.width > 0
 947      }
 948  }
 949  
 950  fn main() {
 951      let rect1 = Rectangle {
 952          width: 30,
 953          height: 50
 954      };
 955  
 956      if rect1.width() {
 957          println!("The rectangle has a nonzero width; it is {}", rect1.width);
 958      }
 959  }
 960  #+END_SRC
 961  
 962  *** Methods with More Parameters
 963  
 964  Let's practice using methods by implementing a second method on the =Rectangle= struct. This time we want an instance of =Rectangle= to take another instance of =Rectangle= and return =true= if the second =Rectangle= can fit completely within =self= (the first =Rectangle=); otherwise, it should return =false=. That is, once we've defined the =can_hold= method, we want to be able to write the program shown in Listing 5-14.
 965  
 966  #+BEGIN_SRC rust
 967  #[derive(Debug)]
 968  struct Rectangle {
 969      width: u32,
 970      height: u32
 971  }
 972  
 973  impl Rectangle {
 974      fn area(&self) -> u32{
 975          self.width * self.height
 976      }
 977  
 978      fn can_hold(&self, other: &Rectangle) -> bool {
 979          self.width > other.width && self.height > other.height
 980      }
 981  }
 982  
 983  fn main(){
 984      let rect1 = Rectangle {
 985      width: 30,
 986          height: 50
 987      };
 988  
 989      let rect2 = Rectangle {
 990          width: 10,
 991          height: 40
 992      };
 993  
 994      let rect3 = Rectangle {
 995          width: 60,
 996          height: 45
 997      };
 998  
 999      println!("Can rect1 hold rect2? {}", rect1.can_hold(&rect2));
1000      println!("Can rect1 hold rect3? {}", rect1.can_hold(&rect3));
1001  }
1002  #+END_SRC
1003  
1004  *** Associated Functions
1005  
1006  All functions defined within an =impl= block are called /associated functions/ because they're associated with the type named after the =impl=. We can define associated functions that don't have =self= as their first parameter (and thus are not methods) because they don't need an instance of the type to work with. We've already used one function like this: the =String::from= function that's defined on the =String= type.
1007  
1008  Associated functions that aren't methods are often used for constructors that will return a new instance of the struct. These are often called =new=, but =new= isn't a special name and isn't built into the language. For example, we could choose to provide an associated function named =square= that would have one dimension parameter and use that as both width and height, thus making it easier to create a square =Rectangle= rather than having to specify the same value twice:
1009  
1010  #+BEGIN_SRC rust
1011  impl Rectangle {
1012      fn square(size: u32) -> Self {
1013          Self {
1014              width: size,
1015              height: size
1016          }
1017      }
1018  }
1019  #+END_SRC
1020  
1021  The =Self= keywords in the return type and in the body of the function are aliases for the type that appears after the =impl= keyword, which in this case is =Rectangle=.
1022  
1023  To call this associated function, we use the =::= syntax with the struct name; =let sq = Rectangle::square(3);= is an example. This function is namespaced by the struct: The =::= syntax is used for both associated functions and namespaces created by modules. We'll discuss modules in Chapter 7.
1024  
1025  *** Multiple impl Blocks
1026  
1027  Each struct is allowed to have multiple =impl= blocks. For example, Listing 5-15 is equivalent to the code shown in Listing 5-16, which has each method in its own =impl= block.
1028  
1029  #+BEGIN_SRC rust
1030  impl Rectangle {
1031      fn area(&self) -> u32 {
1032          self.width * self.height
1033      }
1034  }
1035  
1036  impl Rectangle {
1037      fn can_hold(&self, other: &Rectangle) -> bool {
1038          self.width > other.width && self.height > other.height
1039      }
1040  }
1041  #+END_SRC
1042  Listing 5-16: Rewriting Listing 5-15 using multiple =impl= blocks
1043  
1044  There's no reason to separate these methods into multiple =impl= blocks here, but this is valid syntax. We'll see a case in which multiple =impl= blocks are useful in Chapter 10, where we discuss generic types and traits.
1045  
1046  *** Summary
1047  
1048  Structs let you create custom types that are meaningful for your domain. By using structs, you can keep associated pieces of data connected to each other and nae each piece to make your code clear. In =impl= blocks, you can define functions that are associated with your type, and methods are a kind of associated function that let you specify the behavior that instances of your structs have.
1049  
1050  But structs aren't the only way you can create custom types: Let's turn to Rust's enum feature to add another tool to your toolbox.
1051  
1052  
1053  * Enums and Pattern Matching
1054  In this chapter, we'll look at enumerations, also referred to as /enums/. Enums allow you to define a type by enumerating its possible variants. First we'll define and use an enum to show how an enum can encode meaning along with data. Next, we'll explore a particularly useful enum, called =Option=, which expresses that a value can be either something or nothing. Then, we'll look at how pattern matching in the =match= expression makes it easy to run different code for different values of an enum. Finally, we'll cover how the =if let= construct is another convenient and concise idiom available to handle enums in your code.
1055  
1056  ** Defining an Enum
1057  
1058  Where structs give you a way of grouping together related fields and data, like a =Rectangle= with its =width= and =height=, enums give you a way of saying a value is one of a possible set of values. For example, we may want to say that =Rectangle= is one of a set of possible shapes that also includes =Circle= and =Triangle=. To do this, Rust allows us to encode these possibilities as an enum.
1059  
1060  Let’s look at a situation we might want to express in code and see why enums are useful and more appropriate than structs in this case. Say we need to work with IP addresses. Currently, two major standards are used for IP addresses: version four and version six. Because these are the only possibilities for an IP address that our program will come across, we can enumerate all possible variants, which is where enumeration gets its name.
1061  
1062  Any IP address can be either a version four or a version six address, but not both at the same time. That property of IP addresses makes the enum data structure appropriate because an enum value can only be one of its variants. Both version four and version six addresses are still fundamentally IP addresses, so they should be treated as the same type when the code is handling situations that apply to any kind of IP address.
1063  
1064  We can express this concept in code by defining an =IpAddrKind= enumeration and listing the possible kinds an IP address can be, =V4= and =V6=. These are the variants of the enum:
1065  
1066  #+BEGIN_SRC rust
1067  enum IpAddrKind {
1068      V4,
1069      V6
1070  }
1071  #+END_SRC
1072  
1073  =IpAddrKind= is now a custom data type that we can use elsewhere in our code.
1074  
1075  *** Enum Values
1076  
1077  We can create instances of each of the two variants of =IpAddrKind= like this:
1078  
1079  #+BEGIN_SRC rust
1080  let four = IpAddrKind::V4;
1081  let six = IpAddrKind::V6;
1082  #+END_SRC
1083  
1084  *** The /Option/ Enum
1085  
1086  This section explores a case study of =Option=, which is another enum defined by the standard library. The =Option= type encodes the very common scenario in which a value could be something, or it could be nothing.
1087  
1088  For example, if you request the first item in a non-empty list, you would get a value. If you request the first item in an empty list, you would get nothing. Expressing this concept in terms of the type system means the compiler can check whether you’ve handled all the cases you should be handling; this functionality can prevent bugs that are extremely common in other programming languages.
1089  
1090  Programming language design is often thought of in terms of which features you include, but the features you exclude are important too. Rust doesn’t have the null feature that many other languages have. Null is a value that means there is no value there. In languages with null, variables can always be in one of two states: null or not-null.
1091  
1092  In his 2009 presentation “Null References: The Billion Dollar Mistake,” Tony Hoare, the inventor of null, had this to say:
1093  
1094  #+begin_quote
1095  I call it my billion-dollar mistake. At that time, I was designing the first comprehensive type system for references in an object-oriented language. My goal was to ensure that all use of references should be absolutely safe, with checking performed automatically by the compiler. But I couldn’t resist the temptation to put in a null reference, simply because it was so easy to implement. This has led to innumerable errors, vulnerabilities, and system crashes, which have probably caused a billion dollars of pain and damage in the last forty years.
1096  #+end_quote
1097  
1098  The problem with null values is that if you try to use a null value as a not-null value, you’ll get an error of some kind. Because this null or not-null property is pervasive, it’s extremely easy to make this kind of error.
1099  
1100  However, the concept that null is trying to express is still a useful one: A null is a value that is currently invalid or absent for some reason.
1101  
1102  The problem isn’t really with the concept but with the particular implementation. As such, Rust does not have nulls, but it does have an enum that can encode the concept of a value being present or absent. This enum is =Option<T>=, and it is defined by the standard library as follows:
1103  
1104  #+BEGIN_SRC rust
1105  enum Option<T> {
1106      None,
1107      Some(T)
1108  }
1109  #+END_SRC
1110  
1111  ** The match Control Flow Construct
1112  Rust has an extremely powerful control flow construct called =match= that allows you to compare a value against a series of patterns and then execute code based on which pattern matches. Patterns can be made up of literal values, variable names, wildcards, and many other things; Chapter 19 covers all the different kinds of patterns and what they do. The power of =match= comes from the expressiveness of the patterns and the fact that the compiler confirms that all possible cases are handled.
1113  
1114  Think of a =match= expression as being like a coin-sorting machine: Coins slide down a track with variously sized holes along it, and each coin falls through the first hole it encounters that it fits into. In the same way, values go through each pattern in a =match=, and at the first pattern the value “fits,” the value falls into the associated code block to be used during execution.
1115  
1116  Speaking of coins, let’s use them as an example using =match=! We can write a function that takes an unknown US coin and, in a similar way as the counting machine, determines which coin it is and returns its value in cents, as shown in Listing 6-3.
1117  
1118  #+BEGIN_SRC rust
1119  enum Coin {
1120      Penny,
1121      Nickel,
1122      Dime,
1123      Quarter
1124  }
1125  
1126  fn value_in_cents(coin: Coin) -> u8{
1127      match coin {
1128          Coin::Penny => 1,
1129          Coin::Nickel => 5,
1130          Coin::Dime => 10,
1131          Coin::Quarter => 25,
1132      }
1133  }
1134  #+END_SRC
1135  Listing 6-3: An enum and a =match= expression that has the variants of the enum as its patterns
1136  
1137  Let’s break down the =match= in the =value_in_cents= function. First, we list the =match= keyword followed by an expression, which in this case is the value =coin=. This seems very similar to a conditional expression used with =if=, but there’s a big difference: With =if=, the condition needs to evaluate to a Boolean value, but here it can be any type. The type of =coin= in this example is the =Coin= enum that we defined on the first line.
1138  
1139  Next are the =match= arms. An arm has two parts: a pattern and some code. The first arm here has a pattern that is the value =Coin::Penny= and then the ==>= operator that separates the pattern and the code to run. The code in this case is just the value =1=. Each arm is separated from the next with a comma.
1140  
1141  When the =match= expression executes, it compares the resultant value against the pattern of each arm, in order. If a pattern matches the value, the code associated with that pattern is executed. If that pattern doesn’t match the value, execution continues to the next arm, much as in a coin-sorting machine. We can have as many arms as we need: In Listing 6-3, our match has four arms.
1142  
1143  The code associated with each arm is an expression, and the resultant value of the expression in the matching arm is the value that gets returned for the entire =match= expression.
1144  
1145  We don’t typically use curly brackets if the match arm code is short, as it is in Listing 6-3 where each arm just returns a value. If you want to run multiple lines of code in a match arm, you must use curly brackets, and the comma following the arm is then optional. For example, the following code prints “Lucky penny!” every time the method is called with a =Coin::Penny=, but it still returns the last value of the block, =1=:
1146  
1147  #+BEGIN_SRC rust
1148  fn value_in_cents(coin: Coin) -> u8 {
1149      match coin {
1150          Coin::Penny => {
1151              println!("Lucky penny!");
1152              1
1153          }
1154          Coin::Nickel => 5,
1155          Coin::Dime => 10,
1156          Coin::Quarter => 25
1157      }
1158  }
1159  #+END_SRC
1160  
1161  *** Patterns That Bind to Values
1162  
1163  Another useful feature of match arms is that they can bind to the parts of the values that match the pattern. This is how we can extract values out of enum variants.
1164  
1165  As an example, let’s change one of our enum variants to hold data inside it. From 1999 through 2008, the United States minted quarters with different designs for each of the 50 states on one side. No other coins got state designs, so only quarters have this extra value. We can add this information to our =enum= by changing the =Quarter= variant to include a =UsState= value stored inside it, which we’ve done in Listing 6-4.
1166  
1167  #+BEGIN_SRC rust
1168  #[derive(Debug)]
1169  enum UsState {
1170      Alabama,
1171      Alaska
1172  }
1173  
1174  enum Coin {
1175      Penny,
1176      Nickel,
1177      Dime,
1178      Quarter(UsState)
1179  }
1180  #+END_SRC
1181  Listing 6-4: A =Coin= enum in which the =Quarter= variant also holds a =UsState= value
1182  
1183  Let's imagine that a friend is trying to collect all 50 state quarters. While we sort our loose change by coin type, we'll also call out the name of the state associated with each quarter so that if it's one our friend doesn't have, they can add it to their collection.
1184  
1185  In the match expression for this code, we add a variable called =state= to the pattern that matches values of the variant =Coin::Quarter=. When a =Coin::Quarter= matches, the =state= variable will bind to the value of that quarter's state. Then we can use =state= in the code for that arm, like so:
1186  
1187  #+BEGIN_SRC rust
1188  fn value_in_cents(coin: Coin)-> u8 {
1189      match coin {
1190          Coin::Penny => 1,
1191          Coin::Nickel => 5,
1192          Coin::Dime => 10,
1193          Coin::Quarter(state) => {
1194              println!("State quarter from {state:?}!");
1195              25
1196          }
1197      }
1198  }
1199  #+END_SRC
1200  
1201  If we were to call =value_in_cents(Coin::Quarter(UsState::Alaska))=, =coin= would be =Coin::Quarter(UsState::Alaska)=. When we compare that value with each of the match arms, none of them match until we reach =Coin::Quarter(state)=. At that point, the binding for =state= will be the value =UsState::Alaska=. We can then use that binding in the =println!= expression, thus getting the inner state value out of the =Coin= enum variant for =Quarter=.
1202  
1203  The Option<T> match Pattern
1204  
1205  #+BEGIN_SRC rust
1206  fn plus_one(x: Option<i32>) -> Option<i32> {
1207      match x {
1208          None => None,
1209          Some(i) => Some(i + 1),
1210      }
1211  }
1212  
1213  let five = Some(5);
1214  let six = plus_one(five);
1215  let none = plus_one(None);
1216  #+END_SRC
1217  Listing 6-5: A function that uses a =match= expression on an =Option<i32>=
1218  
1219  Matches are Exhaustive
1220  
1221  ** Concise Control Flow with if let and let...else
1222  * Packages, Crates, and Modules
1223  ** Packages and Crates
1224  The first parts of the module system we'll cover are packages and crates.
1225  
1226  A /crate/ is the smallest amount of code that the Rust compiler considers at a time. Even if you run =rustc= rather than =cargo= and pass a single source code file (as we did all the way back in "Rust Program Basics" in Chapter 1), the compiler considers that file to be a crate. Crates can contain modules, and the modules may be defined in other files that get compiled with the crate, as we'll see in the coming sections.
1227  
1228  A crate can come in one of two forms: a binary crate or a library crate. /Binary/ crates are programs you can compile to an executable that you can run, such as a command line program or a server. Each must have a function called =main= that defines what happens when the executable runs. All the crates we’ve created so far have been binary crates.
1229  
1230  /Library/ crates don’t have a =main= function, and they don’t compile to an executable. Instead, they define functionality intended to be shared with multiple projects. For example, the =rand= crate we used in Chapter 2 provides functionality that generates random numbers. Most of the time when Rustaceans say “crate,” they mean library crate, and they use “crate” interchangeably with the general programming concept of a “library.”
1231  
1232  The /crate/ root is a source file that the Rust compiler starts from and makes up the root module of your crate (we’ll explain modules in depth in “Control Scope and Privacy with Modules”).
1233  
1234  A /package/ is a bundle of one or more crates that provides a set of functionality. A package contains a /Cargo.toml/ file that describes how to build those crates. Cargo is actually a package that contains the binary crate for the command line tool you’ve been using to build your code. The Cargo package also contains a library crate that the binary crate depends on. Other projects can depend on the Cargo library crate to use the same logic the Cargo command line tool uses.
1235  
1236  A package can contain as many binary crates as you like, but at most only one library crate. A package must contain at least one crate, whether that’s a library or binary crate.
1237  
1238  Let’s walk through what happens when we create a package. First, we enter the command =cargo new my-project=:
1239  
1240  #+BEGIN_SRC sh
1241  cargo new my-project
1242  ls my-project
1243  ls my-project/src
1244  #+END_SRC
1245  
1246  After we run =cargo new my-project=, we use =ls= to see what Cargo creates. In the /my-project/ directory, there’s a /Cargo.toml/ file, giving us a package. There’s also a /src/ directory that contains /main.rs/. Open /Cargo.toml/ in your text editor and note that there’s no mention of /src/main.rs/. Cargo follows a convention that src/main.rs is the crate root of a binary crate with the same name as the package. Likewise, Cargo knows that if the package directory contains src/lib.rs, the package contains a library crate with the same name as the package, and src/lib.rs is its crate root. Cargo passes the crate root files to rustc to build the library or binary.
1247  
1248  Here, we have a package that only contains src/main.rs, meaning it only contains a binary crate named my-project. If a package contains src/main.rs and src/lib.rs, it has two crates: a binary and a library, both with the same name as the package. A package can have multiple binary crates by placing files in the src/bin directory: Each file will be a separate binary crate.
1249  
1250  ** Control Scope and Privacy with Modules
1251  In this section, we'll talk about modules and other parts of the module system, namely /paths/, which allow you to name items; the =use= keyword that brings a path into scope; and the =pub= keyword to make items public. We'll also discuss the =as= keyword, external packages, and the glob operator.
1252  
1253  *Modules Cheat Sheet*
1254  
1255  Before we get to the details of modules and paths, here we provide a quick reference on how modules, paths, the =use= keyword, and the =pub= keyword work in the compiler, and how most developers organize their code.
1256  
1257  ** Paths for Referring to an Item in the Module Tree
1258  ** Bringing Paths Into Scope with the use Keyword
1259  ** Separating Modules into Different Files
1260  * Common Collections
1261  ** Storing Lists of Values with Vectors
1262  ** Storing UTF-8 Encoded Text with Strings
1263  ** Storing Keys with Associated Values in Hash Maps
1264  * Error Handling
1265  ** Unrecoverable Errors with panic!
1266  ** Recoverable Errors with Result
1267  ** To panic! or Not to panic!
1268  * Generic Types, Traits, and Lifetimes
1269  ** Generic Data Types
1270  ** Defining Shared Behavior with Traits
1271  ** Validating References with Lifetimes
1272  * Writing Automated Tests
1273  ** How to Write Tests
1274  ** Controlling How Tests Are Run
1275  ** Test Organization
1276  * An I/O Project: Building a Command Line Program
1277  ** Accepting Command Line Arguments
1278  ** Reading a File
1279  ** Refactoring to Improve Modularity and Error Handling
1280  ** Adding Functionality with Test Driven Development
1281  ** Working with Environment Variables
1282  ** Redirecting Errors to Standard Error
1283  * Functional Language Features: Iterators and Closures
1284  ** Closures
1285  ** Processing a Series of Items with Iterators
1286  ** Improving Our I/O Project
1287  ** Performance in Loops vs. Iterators
1288  * More about Cargo and Crates.io
1289  ** Customizing Builds with Release Profiles
1290  ** Publishing a Crate to Crates.io
1291  ** Cargo Workspaces
1292  ** Installing Binaries with cargo install
1293  ** Extending Cargo with Custom Commands
1294  * Smart Pointers
1295  ** Using Box<T> to Point to Data on the Heap
1296  ** Treating Smart Pointers Like Regular References
1297  ** Running Code on Cleanup with the Drop Trait
1298  ** Rc<T>, the Reference Counted Smart Pointer
1299  ** RefCell<T> and the Interior Mutability Pattern
1300  ** Reference Cycles Can Leak Memory
1301  * Fearless Concurrency
1302  ** Using Threads to Run Code Simultaneously
1303  ** Transfer Data Between Threads with Message Passing
1304  ** Shared-State Concurrency
1305  ** Extensible Concurrency with Send and Sync
1306  * Fundamentals of Asynchronous Programming: Async, Await, Futures, and Streams
1307  ** Futures and the Async Syntax
1308  ** Applying Concurrency with Async
1309  ** Working With Any Number of Futures
1310  ** Streams: Futures in Sequence
1311  ** A Closer Look at the Traits for Async
1312  ** Futures, Tasks, and Threads
1313  * Object Oriented Programming Features
1314  ** Characteristics of Object-Oriented Languages
1315  ** Using Trait Objects to Abstract over Shared Behavior
1316  ** Implementing an Object-Oriented Design Pattern
1317  * Patterns and Matching
1318  ** All the Places Patterns Can Be Used
1319  ** Refutability: Whether a Pattern Might Fail to Match
1320  ** Pattern Syntax
1321  * Advanced Features
1322  ** Unsafe Rust
1323  ** Advanced Traits
1324  ** Advanced Types
1325  ** Advanced Functions and Closures
1326  ** Macros
1327  * Final Project: Building a Multithreaded Web Server
1328  ** Building a Single-Threaded Web Server
1329  ** From Single-Threaded to Multithreaded Server
1330  ** Graceful Shutdown and Cleanup
1331  * Appendix
1332  ** A - Keywords
1333  ** B - Operators and Symbols
1334  ** C - Derivable Traits
1335  ** D - Useful Development Tools
1336  ** E - Editions
1337  ** F - Translations of the Book
1338  ** G - How Rust is Made and “Nightly Rust”