{"id":20073645,"url":"https://github.com/ragingwind/rust-programming-language-summary","last_synced_at":"2026-06-04T22:31:38.566Z","repository":{"id":65923535,"uuid":"193787781","full_name":"ragingwind/rust-programming-language-summary","owner":"ragingwind","description":"Summary, Short version of The Rust Programming Language","archived":false,"fork":false,"pushed_at":"2023-04-16T06:55:24.000Z","size":875,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-01T17:13:09.929Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ragingwind.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-06-25T21:47:46.000Z","updated_at":"2023-03-10T11:16:53.000Z","dependencies_parsed_at":"2024-11-13T14:48:32.438Z","dependency_job_id":"655eeae1-8b20-445d-acc9-c4c7ec7f98a4","html_url":"https://github.com/ragingwind/rust-programming-language-summary","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/ragingwind/rust-programming-language-summary","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ragingwind%2Frust-programming-language-summary","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ragingwind%2Frust-programming-language-summary/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ragingwind%2Frust-programming-language-summary/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ragingwind%2Frust-programming-language-summary/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ragingwind","download_url":"https://codeload.github.com/ragingwind/rust-programming-language-summary/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ragingwind%2Frust-programming-language-summary/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33923173,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-04T02:00:06.755Z","response_time":64,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-13T14:47:06.831Z","updated_at":"2026-06-04T22:31:38.546Z","avatar_url":"https://github.com/ragingwind.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"- [The Rust Programming Language Summary](#the-rust-programming-language-summary)\n  - [Version](#version)\n- [Foreword](#foreword)\n- [Introduction](#introduction)\n  - [Who Rust Is For](#who-rust-is-for)\n    - [Teams of Developers](#teams-of-developers)\n    - [Students](#students)\n    - [Companies](#companies)\n    - [Open Source Developers](#open-source-developers)\n    - [People Who Value Speed and Stability](#people-who-value-speed-and-stability)\n- [Getting Started](#getting-started)\n  - [Installation](#installation)\n  - [Hello, World!](#hello-world)\n  - [Hello, Cargo](#hello-cargo)\n- [Programming a Guessing Game](#programming-a-guessing-game)\n  - [Setting Up a New Project](#setting-up-a-new-project)\n- [Processing a Guess](#processing-a-guess)\n- [Common Programming Concepts](#common-programming-concepts)\n  - [Variables and Mutability](#variables-and-mutability)\n  - [Differences Between Variable and Constants](#differences-between-variable-and-constants)\n  - [Shadowing](#shadowing)\n  - [Data Types](#data-types)\n    - [Scalar Types](#scalar-types)\n    - [Compound Types](#compound-types)\n  - [Functions](#functions)\n    - [Parameters](#parameters)\n    - [Statements and Expressions](#statements-and-expressions)\n    - [Functions with Return Values](#functions-with-return-values)\n  - [Comments](#comments)\n  - [Control Flow](#control-flow)\n    - [if expression](#if-expression)\n    - [Repeatition with Loops](#repeatition-with-loops)\n- [Understanding Ownership](#understanding-ownership)\n  - [What is Ownership?](#what-is-ownership)\n    - [Ownership Rules](#ownership-rules)\n    - [Variable Scope](#variable-scope)\n    - [The String Type](#the-string-type)\n    - [Memory and Allocation](#memory-and-allocation)\n    - [Ways Variables and Data Interact: Move](#ways-variables-and-data-interact-move)\n    - [Ways Variables and Data Interact: Clone](#ways-variables-and-data-interact-clone)\n    - [Stack-Only Data: Copy](#stack-only-data-copy)\n    - [Ownership and Function](#ownership-and-function)\n    - [Return Values and Scope](#return-values-and-scope)\n    - [Returning with Tuple](#returning-with-tuple)\n  - [References and Borrowing](#references-and-borrowing)\n    - [Mutable References](#mutable-references)\n      - [Mutable refernces restriction](#mutable-refernces-restriction)\n      - [Multiple mutable refernes by creating a new scope](#multiple-mutable-refernes-by-creating-a-new-scope)\n      - [Immutable references](#immutable-references)\n    - [Dangling References](#dangling-references)\n  - [The Slice Type](#the-slice-type)\n    - [String Slices](#string-slices)\n      - [String literals are slices](#string-literals-are-slices)\n      - [String Slices as Paramters](#string-slices-as-paramters)\n      - [Other slices](#other-slices)\n- [Using Structs to Structre Related Data](#using-structs-to-structre-related-data)\n  - [Defining and Instantiation Structs](#defining-and-instantiation-structs)\n    - [Using the Field Init Shorthand](#using-the-field-init-shorthand)\n    - [Creating instances from other instnace with update value, or struct update syntax](#creating-instances-from-other-instnace-with-update-value-or-struct-update-syntax)\n    - [Using Tuple Structs Without Named Fields to Create Different Types](#using-tuple-structs-without-named-fields-to-create-different-types)\n    - [Unit-like Structs without Any Field](#unit-like-structs-without-any-field)\n  - [An Example Program Using Struct](#an-example-program-using-struct)\n    - [Refactoring with Tuples](#refactoring-with-tuples)\n    - [Refactoring with Structs: Adding More Meaning](#refactoring-with-structs-adding-more-meaning)\n    - [Adding Useful Functionality with Derived Traits](#adding-useful-functionality-with-derived-traits)\n  - [Method Syntax](#method-syntax)\n    - [Defining Methods](#defining-methods)\n    - [Where’s the -\\\u003e Operator?](#wheres-the---operator)\n    - [Methods with More Parameters](#methods-with-more-parameters)\n    - [Associated Functions](#associated-functions)\n    - [Multiple impl Blocks](#multiple-impl-blocks)\n- [Enums and Pattern Matching](#enums-and-pattern-matching)\n  - [Defining an Enum](#defining-an-enum)\n  - [The `Option` Enum and Its Advantages Over Null Values](#the-option-enum-and-its-advantages-over-null-values)\n    - [Use Some Value with various method](#use-some-value-with-various-method)\n    - [Some Value usecases](#some-value-usecases)\n  - [The `match` Control Flow Operator](#the-match-control-flow-operator)\n    - [Patterns That Bind to Values](#patterns-that-bind-to-values)\n    - [Matching with `Option\u003cT\u003e`](#matching-with-optiont)\n    - [Matches Are Exhaustive](#matches-are-exhaustive)\n    - [Catch-all Patterns and the \\_ Placeholder](#catch-all-patterns-and-the-_-placeholder)\n  - [Concise Control FLow with `if let`](#concise-control-flow-with-if-let)\n    - [Match one pattern](#match-one-pattern)\n    - [With else](#with-else)\n- [Managing Growing Projects with Packages, Crates, and Modules](#managing-growing-projects-with-packages-crates-and-modules)\n  - [Packages and Crates](#packages-and-crates)\n  - [Defining Modules to Control Scope and Privacy](#defining-modules-to-control-scope-and-privacy)\n    - [Modules Cheat Sheet](#modules-cheat-sheet)\n    - [Grouping Related Code in Modules](#grouping-related-code-in-modules)\n    - [Paths for Referring to an Item in the Module Tree](#paths-for-referring-to-an-item-in-the-module-tree)\n    - [Starting Relative Paths with `super`](#starting-relative-paths-with-super)\n    - [Making Structs and Enums Public](#making-structs-and-enums-public)\n  - [Bringing Paths into Scope with the use Keyword](#bringing-paths-into-scope-with-the-use-keyword)\n    - [Creating Idiomatic use Paths](#creating-idiomatic-use-paths)\n    - [Providing New Names with the as Keyword](#providing-new-names-with-the-as-keyword)\n    - [Re-exporting Names with pub use](#re-exporting-names-with-pub-use)\n    - [Using External Packages](#using-external-packages)\n    - [Using Nested Paths to Clean Up Large use Lists](#using-nested-paths-to-clean-up-large-use-lists)\n    - [The Glob Operator](#the-glob-operator)\n  - [Separating Modules into Different Files](#separating-modules-into-different-files)\n- [Common Collections](#common-collections)\n  - [Storing Lists of Values with Vectors](#storing-lists-of-values-with-vectors)\n    - [Creating a New Vector](#creating-a-new-vector)\n    - [Update a Vector](#update-a-vector)\n    - [Reading Elements of Vectors](#reading-elements-of-vectors)\n    - [Iterating over the values in a Vector](#iterating-over-the-values-in-a-vector)\n    - [Using an enum to store multiple types](#using-an-enum-to-store-multiple-types)\n    - [Dropping a Vector Drops Its Elements](#dropping-a-vector-drops-its-elements)\n  - [Storing UTF-8 Encoded Text With Strings](#storing-utf-8-encoded-text-with-strings)\n    - [What Is a String?](#what-is-a-string)\n    - [Creating a New String](#creating-a-new-string)\n    - [Updading a String](#updading-a-string)\n      - [Appending to a String with push\\_str and push](#appending-to-a-string-with-push_str-and-push)\n      - [Concatenation with the + Operator or the format! Macro](#concatenation-with-the--operator-or-the-format-macro)\n    - [Indexing into Strings](#indexing-into-strings)\n      - [Internal Representation](#internal-representation)\n      - [Bytes and Scalar Values and Grapheme Clusters! Oh My!](#bytes-and-scalar-values-and-grapheme-clusters-oh-my)\n    - [Slicing Strings](#slicing-strings)\n    - [Methods for Iterating Over Strings](#methods-for-iterating-over-strings)\n    - [Strings Are Not So Simple](#strings-are-not-so-simple)\n  - [Storing Keys with Assoicated Values in Hash Maps](#storing-keys-with-assoicated-values-in-hash-maps)\n    - [Creating a New Hash Map](#creating-a-new-hash-map)\n    - [Accessing Values in a Hash Map](#accessing-values-in-a-hash-map)\n    - [Hash Maps and Ownership](#hash-maps-and-ownership)\n    - [Updating a Hash Map](#updating-a-hash-map)\n      - [Overwriting a Value](#overwriting-a-value)\n      - [Adding a Key and Value Only If a Key Isn’t Present](#adding-a-key-and-value-only-if-a-key-isnt-present)\n      - [Updating a Value Based on the Old Value](#updating-a-value-based-on-the-old-value)\n    - [Hashing Functions](#hashing-functions)\n- [Errror Handling](#errror-handling)\n  - [Unrecoverable Erros With panic!](#unrecoverable-erros-with-panic)\n  - [Using a panic! Backtrace](#using-a-panic-backtrace)\n  - [Recoverable Error with Result](#recoverable-error-with-result)\n    - [Matching on Different Errors](#matching-on-different-errors)\n    - [Alternatives to Using match with Result\\\u003cT, E\\\u003e](#alternatives-to-using-match-with-resultt-e)\n    - [Shortcuts for Panic on Error: unwrap and expect](#shortcuts-for-panic-on-error-unwrap-and-expect)\n    - [Propagating Errors](#propagating-errors)\n      - [A Shortcut for Propagating Errors: the ? Operator](#a-shortcut-for-propagating-errors-the--operator)\n      - [Where The ? Operator Can Be Used](#where-the--operator-can-be-used)\n  - [To panic! or Not ro panic!](#to-panic-or-not-ro-panic)\n    - [Examples, Prototype Code, and Tests](#examples-prototype-code-and-tests)\n    - [Cases in Which You Have More Information Than the Compiler](#cases-in-which-you-have-more-information-than-the-compiler)\n    - [Guidelines for Error Handling](#guidelines-for-error-handling)\n    - [Creating Custom Types for Validation](#creating-custom-types-for-validation)\n- [Generic Types, Traits, and Lifetimes](#generic-types-traits-and-lifetimes)\n  - [Removing Duplication by Extracting a Function](#removing-duplication-by-extracting-a-function)\n  - [Generic Data Types](#generic-data-types)\n    - [In Function Definitions](#in-function-definitions)\n    - [In Struct Definitions](#in-struct-definitions)\n    - [In Enum Definition](#in-enum-definition)\n    - [In Method Definition](#in-method-definition)\n    - [Performance of Code Using Generics](#performance-of-code-using-generics)\n  - [Trais: Defining Shared Behavior](#trais-defining-shared-behavior)\n    - [Defining a Trait](#defining-a-trait)\n    - [Implementing a Trait on a Type](#implementing-a-trait-on-a-type)\n    - [Default Implementations](#default-implementations)\n    - [Traits as Parameters](#traits-as-parameters)\n      - [Trait Bound Syntax](#trait-bound-syntax)\n      - [Specifying Multiple Trait Bounds with the + Syntax](#specifying-multiple-trait-bounds-with-the--syntax)\n      - [Clearer Trait Bounds with where Clauses](#clearer-trait-bounds-with-where-clauses)\n    - [Returning Types that Implement Traits](#returning-types-that-implement-traits)\n    - [Using Trait Bounds to Conditionally Implement Methods](#using-trait-bounds-to-conditionally-implement-methods)\n  - [Validating References with Lifetimes](#validating-references-with-lifetimes)\n    - [Preventing Dangling References with Lifetimes](#preventing-dangling-references-with-lifetimes)\n    - [The Borrow Checker](#the-borrow-checker)\n    - [Generic Lifetimes in Functions](#generic-lifetimes-in-functions)\n      - [Lifetime Annotation Syntax](#lifetime-annotation-syntax)\n    - [Lifetime Annotations in Function Signatures](#lifetime-annotations-in-function-signatures)\n    - [Thinking in Terms of Lifetimes](#thinking-in-terms-of-lifetimes)\n    - [Lifetime Annotations in Struct Definitions](#lifetime-annotations-in-struct-definitions)\n    - [Lifetime Elision](#lifetime-elision)\n    - [Lifetime Annotations in Method Definitions](#lifetime-annotations-in-method-definitions)\n    - [The Static Lifetime](#the-static-lifetime)\n    - [Generic Type Parameters, Trait Bounds, and Lifetimes Together](#generic-type-parameters-trait-bounds-and-lifetimes-together)\n- [Writing Automated Tests](#writing-automated-tests)\n  - [How to Write Tests](#how-to-write-tests)\n    - [The Anatomy of a Test Function](#the-anatomy-of-a-test-function)\n    - [Checking Results with the assert! Macro](#checking-results-with-the-assert-macro)\n    - [Testing Equality with the assert\\_eq! and assert\\_ne! Macros](#testing-equality-with-the-assert_eq-and-assert_ne-macros)\n    - [Adding Custom Failure Messages](#adding-custom-failure-messages)\n    - [Checking for Panics with should\\_panic](#checking-for-panics-with-should_panic)\n    - [Using Result\\\u003cT, E\\\u003e in Tests](#using-resultt-e-in-tests)\n  - [Controlling How Tests Are Run](#controlling-how-tests-are-run)\n    - [Running Tests in Parallel or Consecutively](#running-tests-in-parallel-or-consecutively)\n    - [Showing Function Output](#showing-function-output)\n    - [Running a Subset of Tests by Name](#running-a-subset-of-tests-by-name)\n    - [Ignoring Some Tests Unless Specifically Requested](#ignoring-some-tests-unless-specifically-requested)\n  - [Test Organinzation](#test-organinzation)\n    - [Unit Tests](#unit-tests)\n      - [Testing Private Functions](#testing-private-functions)\n    - [Integration Tests](#integration-tests)\n      - [The tests Directory](#the-tests-directory)\n      - [Submodules in Integration Tests](#submodules-in-integration-tests)\n      - [Integration Tests for Binary Crates](#integration-tests-for-binary-crates)\n- [An I/O Project: Building a Command Line Program](#an-io-project-building-a-command-line-program)\n  - [Accepting Command Line Arguments](#accepting-command-line-arguments)\n    - [Reading the Argument Values](#reading-the-argument-values)\n    - [Saving the Argument Values in Variables](#saving-the-argument-values-in-variables)\n  - [Reading a File](#reading-a-file)\n  - [Refactoring to Improve Modularity and Error Handling](#refactoring-to-improve-modularity-and-error-handling)\n    - [Separation of Concerns for Binary Projects](#separation-of-concerns-for-binary-projects)\n      - [Extracting the Argument Parser](#extracting-the-argument-parser)\n      - [Grouping Configuration Values](#grouping-configuration-values)\n      - [Creating a Constructor for Config](#creating-a-constructor-for-config)\n    - [Fixing the Error Handling](#fixing-the-error-handling)\n      - [Improving the Error Message](#improving-the-error-message)\n      - [Returning a Result Instead of Calling panic!](#returning-a-result-instead-of-calling-panic)\n      - [Calling Config::build and Handling Errors](#calling-configbuild-and-handling-errors)\n    - [Extracting Logic from main](#extracting-logic-from-main)\n      - [Returning Errors from the run Function](#returning-errors-from-the-run-function)\n      - [Handling Errors Returned from run in main](#handling-errors-returned-from-run-in-main)\n    - [Splitting Code into a Library Crate](#splitting-code-into-a-library-crate)\n  - [Developing the Library’s Functionality with Test-Driven Development](#developing-the-librarys-functionality-with-test-driven-development)\n    - [Writing a Failing Test](#writing-a-failing-test)\n    - [Writing Code to Pass the Test](#writing-code-to-pass-the-test)\n      - [Using the search Function in the run Function](#using-the-search-function-in-the-run-function)\n  - [Working with Environment Variables](#working-with-environment-variables)\n    - [Writing a Failing Test for the Case-Insensitive search Function](#writing-a-failing-test-for-the-case-insensitive-search-function)\n    - [Implementing the search\\_case\\_insensitive Function](#implementing-the-search_case_insensitive-function)\n  - [Writing Error Messages to Standard Error Instead of Standard Output](#writing-error-messages-to-standard-error-instead-of-standard-output)\n    - [Checking Where Errors Are Written](#checking-where-errors-are-written)\n    - [Printing Errors to Standard Error](#printing-errors-to-standard-error)\n- [Functional Language Features: Iterators and Closures](#functional-language-features-iterators-and-closures)\n  - [Closures: Anonymous Functions that Can Capture Their Environment](#closures-anonymous-functions-that-can-capture-their-environment)\n    - [Capturing the Environment with Closures](#capturing-the-environment-with-closures)\n    - [Closure Type Inference and Annotation](#closure-type-inference-and-annotation)\n    - [Capturing References or Moving Ownership](#capturing-references-or-moving-ownership)\n    - [Moving Captured Values Out of Closures and the Fn Traits](#moving-captured-values-out-of-closures-and-the-fn-traits)\n  - [Processing a Series of Items with Iterators](#processing-a-series-of-items-with-iterators)\n    - [The Iterator Trait and the next Method](#the-iterator-trait-and-the-next-method)\n    - [Methods that Consume the Iterator](#methods-that-consume-the-iterator)\n    - [Methods that Produce Other Iterators](#methods-that-produce-other-iterators)\n    - [Using Closures that Capture Their Environment](#using-closures-that-capture-their-environment)\n  - [Improving Our I/O Project](#improving-our-io-project)\n    - [Removing a clone Using an Iterator](#removing-a-clone-using-an-iterator)\n      - [Using the Returned Iterator Directly](#using-the-returned-iterator-directly)\n      - [Using Iterator Trait Methods Instead of Indexing](#using-iterator-trait-methods-instead-of-indexing)\n    - [Making Code Clearer with Iterator Adaptors](#making-code-clearer-with-iterator-adaptors)\n    - [Choosing Between Loops or Iterators](#choosing-between-loops-or-iterators)\n  - [Comparing Performance: Loops vs. Iterators](#comparing-performance-loops-vs-iterators)\n- [More about Cargo and Crates.io](#more-about-cargo-and-cratesio)\n  - [Customizing Builds with Release Profiles](#customizing-builds-with-release-profiles)\n  - [Publishing a Crate to Crates.io](#publishing-a-crate-to-cratesio)\n    - [Making Useful Documentation Comments](#making-useful-documentation-comments)\n      - [Commonly Used Sections](#commonly-used-sections)\n      - [Documentation Comments as Tests](#documentation-comments-as-tests)\n      - [Commenting Contained Items](#commenting-contained-items)\n    - [Exporting a Convenient Public API with pub use](#exporting-a-convenient-public-api-with-pub-use)\n    - [Setting Up a Crates.io Account](#setting-up-a-cratesio-account)\n    - [Adding Metadata to a New Crate](#adding-metadata-to-a-new-crate)\n    - [Publishing to Crates.io](#publishing-to-cratesio)\n    - [Publishing a New Version of an Existing Crate](#publishing-a-new-version-of-an-existing-crate)\n    - [Deprecating Versions from Crates.io with cargo yank](#deprecating-versions-from-cratesio-with-cargo-yank)\n  - [Cargo Workspaces](#cargo-workspaces)\n    - [Creating a Workspace](#creating-a-workspace)\n    - [Creating the Second Package in the Workspace](#creating-the-second-package-in-the-workspace)\n      - [Depending on an External Package in a Workspace](#depending-on-an-external-package-in-a-workspace)\n      - [Adding a Test to a Workspace](#adding-a-test-to-a-workspace)\n  - [Installing Binaries from Crates.io with cargo install](#installing-binaries-from-cratesio-with-cargo-install)\n  - [Extending Cargo with Custom Commands](#extending-cargo-with-custom-commands)\n- [Smart Pointers](#smart-pointers)\n  - [Using \\`Box to Point to Data on he Heap](#using-box-to-point-to-data-on-he-heap)\n    - [Using a Box to Store Data on the Heap](#using-a-box-to-store-data-on-the-heap)\n    - [Enabling Recursive Types with Boxes](#enabling-recursive-types-with-boxes)\n      - [More Information About the Cons List](#more-information-about-the-cons-list)\n      - [Computing the Size of a Non-Recursive Type](#computing-the-size-of-a-non-recursive-type)\n      - [Using Box to Get a Recursive Type with a Known Size](#using-box-to-get-a-recursive-type-with-a-known-size)\n  - [Treating Smart Pointers Like Regular References with the Deref Trait](#treating-smart-pointers-like-regular-references-with-the-deref-trait)\n    - [Following the Pointer to the Value](#following-the-pointer-to-the-value)\n    - [Using Box Like a Reference](#using-box-like-a-reference)\n    - [Defining Our Own Smart Pointer](#defining-our-own-smart-pointer)\n    - [Treating a Type Like a Reference by Implementing the Deref Trait](#treating-a-type-like-a-reference-by-implementing-the-deref-trait)\n    - [Implicit Deref Coercions with Functions and Methods](#implicit-deref-coercions-with-functions-and-methods)\n    - [How Deref Coercion Interacts with Mutability](#how-deref-coercion-interacts-with-mutability)\n  - [Running Code on Cleanup with the `Drop` Trait](#running-code-on-cleanup-with-the-drop-trait)\n    - [Dropping a Value Early with std::mem::drop](#dropping-a-value-early-with-stdmemdrop)\n  - [Rc, the Reference Counted Smart Pointer](#rc-the-reference-counted-smart-pointer)\n  - [Rc, the Reference Counted Smart Pointer](#rc-the-reference-counted-smart-pointer-1)\n    - [Using Rc to Share Data](#using-rc-to-share-data)\n    - [Cloning an Rc Increases the Reference Count](#cloning-an-rc-increases-the-reference-count)\n  - [RefCell and the Interior Mutability Pattern](#refcell-and-the-interior-mutability-pattern)\n  - [RefCell and the Interior Mutability Pattern](#refcell-and-the-interior-mutability-pattern-1)\n    - [Enforcing Borrowing Rules at Runtime with RefCell](#enforcing-borrowing-rules-at-runtime-with-refcell)\n    - [Interior Mutability: A Mutable Borrow to an Immutable Value](#interior-mutability-a-mutable-borrow-to-an-immutable-value)\n      - [A Use Case for Interior Mutability: Mock Objects](#a-use-case-for-interior-mutability-mock-objects)\n      - [Keeping Track of Borrows at Runtime with RefCell](#keeping-track-of-borrows-at-runtime-with-refcell)\n    - [Having Multiple Owners of Mutable Data by Combining Rc and RefCell](#having-multiple-owners-of-mutable-data-by-combining-rc-and-refcell)\n  - [Reference Cycles Can Leak Memory](#reference-cycles-can-leak-memory)\n    - [Creating a Reference Cycle](#creating-a-reference-cycle)\n    - [Preventing Reference Cycles: Turning an Rc into a Weak](#preventing-reference-cycles-turning-an-rc-into-a-weak)\n      - [Creating a Tree Data Structure: a Node with Child Nodes](#creating-a-tree-data-structure-a-node-with-child-nodes)\n      - [Adding a Reference from a Child to Its Parent](#adding-a-reference-from-a-child-to-its-parent)\n      - [Visualizing Changes to strong\\_count and weak\\_count](#visualizing-changes-to-strong_count-and-weak_count)\n- [Fearless Concurrency](#fearless-concurrency)\n  - [Using Threads to Run Code Simultaneously](#using-threads-to-run-code-simultaneously)\n    - [Creating a New Thread with spawn](#creating-a-new-thread-with-spawn)\n    - [Waiting for All Threads to Finish Using join Handles](#waiting-for-all-threads-to-finish-using-join-handles)\n    - [Using move Closures with Threads](#using-move-closures-with-threads)\n    - [Using Message Passing to Transfer Data Between Threads](#using-message-passing-to-transfer-data-between-threads)\n    - [Channels and Ownership Transference](#channels-and-ownership-transference)\n    - [Sending Multiple Values and Seeing the Receiver Waiting](#sending-multiple-values-and-seeing-the-receiver-waiting)\n    - [Creating Multiple Producers by Cloning the Transmitter](#creating-multiple-producers-by-cloning-the-transmitter)\n  - [Shared-State Concurrency](#shared-state-concurrency)\n    - [Using Mutexes to Allow Access to Data from One Thread at a Time](#using-mutexes-to-allow-access-to-data-from-one-thread-at-a-time)\n      - [The API of Mutex](#the-api-of-mutex)\n      - [Sharing a Mutex Between Multiple Threads](#sharing-a-mutex-between-multiple-threads)\n      - [Multiple Ownership with Multiple Threads](#multiple-ownership-with-multiple-threads)\n      - [Atomic Reference Counting with Arc](#atomic-reference-counting-with-arc)\n    - [Similarities Between RefCell/Rc and Mutex/Arc](#similarities-between-refcellrc-and-mutexarc)\n  - [Extensible Concurrency with the Sync and Send Traits](#extensible-concurrency-with-the-sync-and-send-traits)\n    - [Allowing Transference of Ownership Between Threads with Send](#allowing-transference-of-ownership-between-threads-with-send)\n    - [Allowing Access from Multiple Threads with Sync](#allowing-access-from-multiple-threads-with-sync)\n    - [Implementing Send and Sync Manually Is Unsafe](#implementing-send-and-sync-manually-is-unsafe)\n- [Object Oriented Programming Features of Rust](#object-oriented-programming-features-of-rust)\n  - [Characteristics of Object-Oriented Languages](#characteristics-of-object-oriented-languages)\n    - [Objects Contain Data and Behavior](#objects-contain-data-and-behavior)\n    - [Encapsulation that Hides Implementation Details](#encapsulation-that-hides-implementation-details)\n    - [Inheritance as a Type System and as Code Sharing](#inheritance-as-a-type-system-and-as-code-sharing)\n  - [Using Trait Objects that Allow for Values of Different Types](#using-trait-objects-that-allow-for-values-of-different-types)\n    - [Defining a Trait for Common Behavior](#defining-a-trait-for-common-behavior)\n    - [Implementing the Trait](#implementing-the-trait)\n    - [Trait Objects Perform Dynamic Dispatch](#trait-objects-perform-dynamic-dispatch)\n  - [Implementing an Object-Oriented Design Pattern](#implementing-an-object-oriented-design-pattern)\n    - [Defining Post and Creating a New Instance in the Draft State](#defining-post-and-creating-a-new-instance-in-the-draft-state)\n    - [Storing the Text of the Post Content](#storing-the-text-of-the-post-content)\n    - [Ensuring the Content of a Draft Post Is Empty](#ensuring-the-content-of-a-draft-post-is-empty)\n    - [Requesting a Review of the Post Changes Its State](#requesting-a-review-of-the-post-changes-its-state)\n    - [Adding approve to Change the Behavior of content](#adding-approve-to-change-the-behavior-of-content)\n    - [Trade-offs of the State Pattern](#trade-offs-of-the-state-pattern)\n    - [Encoding States and Behavior as Types](#encoding-states-and-behavior-as-types)\n    - [Implementing Transitions as Transformations into Different Types](#implementing-transitions-as-transformations-into-different-types)\n- [Patterns and Matching](#patterns-and-matching)\n  - [All the Places Patterns Can Be Used](#all-the-places-patterns-can-be-used)\n    - [match Arms](#match-arms)\n  - [All the Places Patterns Can be Used](#all-the-places-patterns-can-be-used-1)\n    - [Conditional `if let` Expressions](#conditional-if-let-expressions)\n    - [`while let` Conditional Loops](#while-let-conditional-loops)\n    - [`for` Loops](#for-loops)\n    - [`let` Statements](#let-statements)\n    - [Function Parameters](#function-parameters)\n  - [Refutability: Whether a Pattern Might Fail to Match](#refutability-whether-a-pattern-might-fail-to-match)\n  - [Pattern Syntax](#pattern-syntax)\n    - [Matching Literals](#matching-literals)\n    - [Matching Named Variables](#matching-named-variables)\n    - [Multiple Patterns](#multiple-patterns)\n    - [Matching Ranges of Values with ..=](#matching-ranges-of-values-with-)\n    - [Destructuring to Break Apart Values](#destructuring-to-break-apart-values)\n      - [Destructuring Structs](#destructuring-structs)\n      - [Destructuring Enums](#destructuring-enums)\n      - [Destructuring Nested Structs and Enums](#destructuring-nested-structs-and-enums)\n      - [Destructuring Structs and Tuples](#destructuring-structs-and-tuples)\n    - [Ignoring Values in a Pattern](#ignoring-values-in-a-pattern)\n      - [Ignoring an Entire Value with \\_](#ignoring-an-entire-value-with-_)\n      - [Ignoring Parts of a Value with a Nested \\_](#ignoring-parts-of-a-value-with-a-nested-_)\n      - [Ignoring an Unused Variable by Starting Its Name with \\_](#ignoring-an-unused-variable-by-starting-its-name-with-_)\n      - [Ignoring Remaining Parts of a Value with ..](#ignoring-remaining-parts-of-a-value-with-)\n    - [Extra Conditionals with Match Guards](#extra-conditionals-with-match-guards)\n    - [@ Bindings](#-bindings)\n- [Advanced Features](#advanced-features)\n  - [Unsafe Rust](#unsafe-rust)\n    - [Unsafe Superpowers](#unsafe-superpowers)\n    - [Dereferencing a Raw Pointer](#dereferencing-a-raw-pointer)\n    - [Calling an Unsafe Function or Method](#calling-an-unsafe-function-or-method)\n    - [Creating a Safe Abstraction over Unsafe Code](#creating-a-safe-abstraction-over-unsafe-code)\n      - [Using extern Functions to Call External Code](#using-extern-functions-to-call-external-code)\n      - [Calling Rust Functions from Other Languages](#calling-rust-functions-from-other-languages)\n    - [Accessing or Modifying a Mutable Static Variable](#accessing-or-modifying-a-mutable-static-variable)\n    - [Implementing an Unsafe Trait](#implementing-an-unsafe-trait)\n    - [Accessing Fields of a Union](#accessing-fields-of-a-union)\n    - [When to Use Unsafe Code](#when-to-use-unsafe-code)\n  - [Advanced Traits](#advanced-traits)\n    - [Specifying Placeholder Types in Trait Definitions with Associated Types](#specifying-placeholder-types-in-trait-definitions-with-associated-types)\n    - [Default Generic Type Parameters and Operator Overloading](#default-generic-type-parameters-and-operator-overloading)\n    - [Fully Qualified Syntax for Disambiguation: Calling Methods with the Same Name](#fully-qualified-syntax-for-disambiguation-calling-methods-with-the-same-name)\n    - [Using Supertraits to Require One Trait’s Functionality Within Another Trait](#using-supertraits-to-require-one-traits-functionality-within-another-trait)\n    - [Using the Newtype Pattern to Implement External Traits on External Types](#using-the-newtype-pattern-to-implement-external-traits-on-external-types)\n  - [Advanced Types](#advanced-types)\n    - [Using the Newtype Pattern for Type Safety and Abstraction](#using-the-newtype-pattern-for-type-safety-and-abstraction)\n    - [Creating Type Synonyms with Type Aliases](#creating-type-synonyms-with-type-aliases)\n    - [The Never Type that Never Returns](#the-never-type-that-never-returns)\n    - [Dynamically Sized Types(DST) and the Sized Trait](#dynamically-sized-typesdst-and-the-sized-trait)\n  - [Advanced Functions \\\u0026 Closures](#advanced-functions--closures)\n    - [Function Pointers](#function-pointers)\n    - [Returning Closures](#returning-closures)\n  - [Macros](#macros)\n    - [The Difference Between Macros and Functions](#the-difference-between-macros-and-functions)\n    - [Declarative Macros with macro\\_rules! for General Metaprogramming](#declarative-macros-with-macro_rules-for-general-metaprogramming)\n    - [Procedural Macros for Generating Code from Attributes](#procedural-macros-for-generating-code-from-attributes)\n    - [How to Write a Custom derive Macro](#how-to-write-a-custom-derive-macro)\n    - [Attribute-like macros](#attribute-like-macros)\n    - [Function-like macros](#function-like-macros)\n- [Final Project: Building a Multithreaded Web Server](#final-project-building-a-multithreaded-web-server)\n  - [Building a Single-Threaded Web Server](#building-a-single-threaded-web-server)\n    - [Listening to the TCP Connection](#listening-to-the-tcp-connection)\n    - [Reading the Request](#reading-the-request)\n    - [A Closer Look at an HTTP Request](#a-closer-look-at-an-http-request)\n    - [Writing a Response](#writing-a-response)\n    - [Returning Real HTML](#returning-real-html)\n    - [Validating the Request and Selectively Responding](#validating-the-request-and-selectively-responding)\n  - [A Touch of Refactoring](#a-touch-of-refactoring)\n  - [Turning Our Single-Threaded Server into a Multithreaded Server](#turning-our-single-threaded-server-into-a-multithreaded-server)\n    - [Simulating a Slow Request in the Current Server Implementation](#simulating-a-slow-request-in-the-current-server-implementation)\n    - [Improving Throughput with a Thread Pool](#improving-throughput-with-a-thread-pool)\n      - [Spawning a Thread for Each Request](#spawning-a-thread-for-each-request)\n      - [Creating a Finite Number of Threads](#creating-a-finite-number-of-threads)\n      - [Building ThreadPool Using Compiler Driven Development](#building-threadpool-using-compiler-driven-development)\n      - [Validating the Number of Threads in new](#validating-the-number-of-threads-in-new)\n      - [Creating Space to Store the Threads](#creating-space-to-store-the-threads)\n      - [A Worker Struct Responsible for Sending Code from the ThreadPool to a Thread](#a-worker-struct-responsible-for-sending-code-from-the-threadpool-to-a-thread)\n      - [Sending Requests to Threads via Channels](#sending-requests-to-threads-via-channels)\n      - [Implementing the execute Method](#implementing-the-execute-method)\n  - [Graceful Shutdown and Cleanup](#graceful-shutdown-and-cleanup)\n    - [Implementing the Drop Trait on ThreadPool](#implementing-the-drop-trait-on-threadpool)\n    - [Signaling to the Threads to Stop Listening for Jobs](#signaling-to-the-threads-to-stop-listening-for-jobs)\n\n# [The Rust Programming Language](https://doc.rust-lang.org/book/) Summary\n\n\u003e Summary, Short version of The Rust Programming Language.\n\n## Version\n\n- Updated on 2023-02 with Rust 1.65 over version aka 2021 edition\n\n# Foreword\n\n- Rust empowers you to reach farther, to program with confidence in a wider variety of domains then did before\n\n- Not only low-level systems programming, ergonomic enough to make CLI apps, web servers, web app, Raspberry Pi, and many other kinds of code quite pleasant to write\n\n# Introduction\n\n## Who Rust Is For\n\n### Teams of Developers\n\nRust is proving to be a productive tools for collaborating among large teams of developer\n\n- Cargo, dependency manager and build tool\n- Rustfmt, formatting tools to ensure a consistent coding style\n- The Rust Language Server for IDE integrations for code completion and iline error message\n\n### Students\n\n- For students who are interested in learning about system concepts\n\n- The community is very welcoming and happy to answer student questions\n\n### Companies\n\n- Hundreds of companies, large and small, use Rust in production for a variety of tasks\n\n- CLI 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\n\n### Open Source Developers\n\n- For people who want to build the Rust programming language, community, developer tools, and libraries\n\n### People Who Value Speed and Stability\n\n- For people who crave speed and stability in a language\n\n- The Rust compiler’s checks ensure stability through feature additions and refactoring\n\n- By striving for zero-cost abstractions, higher-level features that compile to lower-level code as fast as code written manually\n\n- Rust’s greatest ambition is to eliminate the trade-offs that programmers have accepted for decades by providing safety and productivity, speed and ergonomics\n\n# Getting Started\n\n## Installation\n\n- Run `curl https://sh.rustup.rs -sSf | sh` to download `rustup`\n\n  - `rustup`: command line tool for managing Rust version and tools\n\n- Add the following line to your env `export PATH=\"$HOME/.cargo/bin:$PATH\"`\n\n- If installation is already done, run `rustup update`\n\n  - To uninstall, `rustup self uninstall`\n\n- On macOS, we need xcode command line tools by using `xcode-select --install`\n\n## Hello, World!\n\n- Create a project directory\n\n```sh\nmkdir hello_world\ncd hello_world\n```\n\n- New open the main.rs file then save with belows:\n\n```rust\n// main.rs\nfn main() {\n  println!(\"Hello, world!\"); // `!` is macro. end with ';'\n}\n```\n\n- Compile main.rs with `rustc`\n\n```sh\n$ rustc main.rs\n$ ./main\n```\n\n## Hello, Cargo\n\n- Cargo is Rust's build system and package manager\n\n- `cargo new $PROJECT_NAME` to create a project\n\n  - `-—bin` extra option for executable binary\n  - `-—lib` extra option for library\n\n- carg ogenerate Cargo.toml in TOML format\n\n```rust\n[package]\nname = \"hello_cargo\"\nversion = \"0.1.0\"\nedition = \"2021\"\n\n[dependencies]\n```\n\n- Building and running a Cargo projects\n\n```sh\n# building\n$ cargo build\n\n# running\n$ ./target/debug/hello_cargo\nor\n$ cargo run\n\n# checking before build\ncargo check\n\n# update crates\ncargo update\n```\n\n# Programming a Guessing Game\n\nHand-on project, you will lean about let, match, methods, asscicated function, external crates and more\n\n## Setting Up a New Project\n\n- Create a new project and run\n\n```sh\n$ cargo new guessing_game --bin\n$ cargo ru\n```\n\n# Processing a Guess\n\n```rust\nuse std::io;\nuse std::cmp::Ordering;\n// use external crate rand, see Cargo.toml\nuse rand::Rng;\n\nfn main() {\n    // print message\n    println!(\"Guess the number!\");\n\n    // gen_range is de\n    let secret_number = rand::thread_rng().gen_range(1..=101);\n\n    println!(\"the serect number is: {}\", secret_number);\n\n    loop {\n        println!(\"Please input your guess.\");\n\n        // immutable variable to save user input\n        let mut guess = String::new();\n\n        io::stdin()\n            // read stdio buffer and write it to guess\n            .read_line(\u0026mut guess)\n            .expect(\"Failed to read line\");\n\n        // handling invalid input\n        let guess: u32 = match guess.trim().parse() {\n            // convert to u32\n            Ok(num) =\u003e num,\n            Err(_) =\u003e continue,\n        };\n\n        println!(\"You guessed: {}\", guess);\n\n        // match expression to compare guess and secret_number\n        match guess.cmp(\u0026secret_number) {\n            // Ordering type is another enum, Less, Greater, Equal\n            Ordering::Less =\u003e println!(\"Too small!\"),\n            Ordering::Greater =\u003e println!(\"Too big!\"),\n            Ordering::Equal =\u003e {\n                println!(\"You win!\");\n                // quite the loop\n                break;\n            }\n        }\n    }\n}\n```\n\n# Common Programming Concepts\n\n\u003e This chapter covers concepts that appear in almost every programming language and how they work in Rust.\n\n## Variables and Mutability\n\n- By default, variables are immutable\n- Using `mut` to make a variable as mutable\n\n## Differences Between Variable and Constants\n\n- No `mut` for constants\n- Constants can be declared in any scope\n- Set with constant expression\n\n## Shadowing\n\n- Without `let` we will get compile error\n\n```rust\nfn main() {\n    let x = 5;\n    let x = x + 1;\n    let x = x * 2;\n\n    // (5 + 1) * 2 = 12\n    println!(\"The value of x is: {}\", x);\n}\n```\n\n- We can change the type, reuse the same name\n\n```rust\n// reuse the variable with the another type\nlet spaces = \"   \"; // string type\nlet spaces = spaces.len(); // bind new type value\n\n// compile error with using mut\nlet mut spaces = \"   \";\nspaces = spaces.len();\n```\n\n## Data Types\n\n### Scalar Types\n\nSingle value: integers, floating-point numbers, Booleans, and characters\n\n- Integers Types: i/u8, i/u16, i/u32, i/u64, i/u128, i/usize\n- Intergers literals:\n  - Decimal: `98_222` // 98.222\n  - Hex: 0xff\n  - Octal: 0o77\n  - Binary?: `0b1111_0000` // 11110000\n  - Byte(u8):` b'A'`\n  - u8: `57u8`\n- Overflow, in debug, it panic, in production, wrapping\n- Floating-Point: f64, default, same speeed as f32, double precision. f32, single precision\n- Numberic Operations: `+, -, *, / , %`\n- The Boolean Type: `true, false`\n- The Character Type: unicode scalar values range from U+0000 to u+D7FFF and U+E000 to U+10FFFF\n  - `char`\n  - \"string literal\"\n\n### Compound Types\n\n- Group multiple values into one type, tuple and arrays\n- The Tuple Type, fixed length, once declared, cannot grow or shirnk in size\n\n```rust\n// decalration\nlet tup: (i32, f64, u8) = (500, 6.4, 1);\n\n// access with index\nlet five_hundred = tup.0; // start with 0\nlet six_point_four = tup.1;\nlet one = tup.2;\n\n// destructure\nlet tup = (500, 6.4, 1);\nlet (x, y, z) = tup;\n```\n\n- The Array Type, collection of multiple values with the same type, fixed length unlike other languages.\n\n```rust\n// declaration\nlet a = [1, 2, 3, 4, 5];\nlet b: [i32; 5] = [1, 2, 3, 4, 5];\n\n// accessing\nlet first = a[0];\n\n// out of indexing, rust protects this kind of error from memory corruption\nlet index = 10;\nlet run_time_error = a[index];\n```\n\n## Functions\n\n- Using snake case\n- Defining function anywhere\n\n### Parameters\n\n```rust\nfn another_function(x) {\n  println!(\"The value of x is: {}\", x);\n}\n\nfn another_function(y: i32) {\n  println!(\"The value of y is: {}\", y);\n}\n```\n\n### Statements and Expressions\n\n```rust\n\nfn statement_fn() {\n  // Statements are instructions that perform some action and do not return a value\n  println!(\"function!\");\n}\n\nfn main() {\n  let x = 5;\n  let y = { // Expressions evaluate to a resultant value\n    let x = 3;\n    x + 1 // no semicolun at the end of the expression\n  }\n\n  println!(\"y is {}\", y); // y is 4\n}\n```\n\n### Functions with Return Values\n\n```rust\nfn five() -\u003e i32 {\n  5 // end of expression without return\n}\n\nfn plus_one(x: i32) -\u003e i32 {\n  x + 1\n}\n```\n\n## Comments\n\n- Commenting with two slashes and continue until the end of line\n\n## Control Flow\n\n### if expression\n\n```rust\nlet number = 3;\n\nif number \u003c 5 {\n  println!(\"number is under 5\");\n} else {\n  println!(\"number isnot under 5\");\n}\n\n// error, missmatch type, expected `bool`, found integer\n// must be `number != 0`\nif number {\n  ...\n}\n\n// handling multiple if\nif number % 4 == 0 {\n  println!(\"number is divisible by 4\");\n} else if number % 3 == 0 {\n  println!(\"number is divisible by 3\");\n} else if number % 2 == 0 {\n  println!(\"number is divisible by 2\");\n} else {\n  println!(\"number is not divisible by 4, 3, or 2\");\n}\n\n// if in a let statement\nlet condition = true;\n// must be return same type variable\nlet number = if confition { 5 } else { 6 };\n```\n\n### Repeatition with Loops\n\n- Returning Values from Loops\n\n```rust\nfn main() {\n  let mut counter = 0;\n  let result = loop { // loop\n    counter += 1;\n\n    println!(\"again!\");\n\n    if counter == 10 {\n      // return value from loop\n      break counter * 2 // return 10 * 2\n    }\n  }\n\n   println!(\"The result is {result}\"); // The result is 20\n}\n```\n\n- Loop Labels to Disambiguate Between Multiple Loops\n\n```rust\nfn main() {\n  let mut count = 0;\n  'counting_up: loop {\n    println!(\"count = {count}\");\n    let mut remaining = 10;\n\n    loop {\n      println!(\"remaining = {remaining}\");\n      if remaining == 9 {\n        break;\n      }\n      if count == 2 {\n        // break parent loop, \n        break 'counting_up;\n      }\n      remaining -= 1;\n    }\n\n    count += 1;\n  }\n  println!(\"End count = {count}\");\n}\n```\n\n- Contitional Loops with while\n\n```rust\nfn main() {\n  let mut number = 3;\n  while number != 0 {\n    println!(\"again!\");\n    number = number - 1;\n  }\n}\n```\n\n- Looping Through a Collection with for\n\n```rust\nfn main() {\n  let a = [10, 20, 30, 40, 50];\n  for element in a {\n    println!(\"val is {}\", element);\n  }\n\n  for number in (1..4).rev() {\n    println!(\"val is {}\", number);\n  }\n}\n```\n\n# Understanding Ownership\n\n- Enables Rust to make memory safety guarantees without needing a `garbage collector`.\n- In Ruet, memory is managed through a system of ownership `with a set of rules that compiler checks at compile time`\n\n## What is Ownership?\n\n- Ownership is a set of rules that govern how a Rust program manages memory\n- Rust uses a third approach: memory is managed through a system of ownership with a set of rules that the compiler checks\n\n### Ownership Rules\n\n- Each value in Rust has an owner\n- There can only be one owner at a time\n- When the owner goes out of scope, the value will be dopped\n\n### Variable Scope\n\n```rust\n{                     // s is not valid here, it's not yet declared\n  let s = \"hello\";    // s is valid from this point forward\n  // do stuff with s\n}                     // this scope is over, and s is no longer valid\n```\n\n### The String Type\n\n\u003e Rust has a second string type, String. This type manages data allocated on the heap and as such is able to store an amount of text that is unknown to us at compile time\n\n```rust\nlet s = String::from(\"hello\"); // string is allocated on the heap, String:: is namespace\n\nlet mut s2 = String::from(\"hello\");\ns2.push_str(\", world!\");\n```\n\n### Memory and Allocation\n\n- Rust takes a different path: the memory is automatically returned once the variable that owns it goes out of scope\n- When a variable goes out of scope, Rust calls a special function for us. This function is called `drop`\n- Rust calls `drop` automatically at the closing curly bracket\n\n```rust\n{\n  let s = String::from(\"hello\"); // s is valid from this point forward\n  ...\n} // this scope is now over, s goes out of scope, and s is no longer valid\n```\n\n### Ways Variables and Data Interact: Move\n\n```rust\n// these two 5 values are pused to onto the stack\nlet x = 5;\nlet y = x;\n\n// two of containers for the string data (ptr, len, and capacity)\nlet s1 = String::from(\"hello\");\nlet s2 = s1; // s1 string data is moved to s2, Rust invalidates the first variable, instead of being called a shallow copy\n\nprintln!(\"{}, world!\", s1); // error, string data has been moved to s2\n```\n\n- Rust will never automatically create “deep” copies of your data. Therefore, `any automatic copying` can be assumed to be inexpensive in terms of runtime performance.\n\n### Ways Variables and Data Interact: Clone\n\n```rust\nlet s1 = String::from(\"hello\");\nlet s2 = s1.clone(); // using deep copy to call clone()\n\nprintln!(\"s1 = {}, s2 = {}\", s1, s2);\n```\n\n### Stack-Only Data: Copy\n\n- Types such as integers that have a known size at compile time are stored entirely on the stack, so copies of the actual values are quick to make.\n\n```rust\nlet x = 5;\nlet y = x; // x is stil valid after x moved to y\n\nprintln!(\"x = {}, y = {}\", x, y)\n```\n\n- Rust has a `special annotation called the Copy` trait that we can place on types that are stored on the stack, as integers are\n- Rust won’t let us annotate a type with Copy if the type, or any of its parts, has implemented the `Drop trait`.\n- Any group of simple scalar values can implement `Copy`, some of the types that implement Copy:\n  - All the integer types, such as `u32`\n  - The Boolean type `bool`, with values `true` and `false`\n  - All the floating point type, such as `f64`\n  - The character type `char`\n  - Tuples, if they only contain types that are also `Copy`. For example, `(i32, i32)` is `Copy` but `(i32, string)` is not\n\n### Ownership and Function\n\n- Passing a variable to a function will `move or copy`, just as assgiment does\n\n```rust\nfn main() {\n  let s = String::from(\"hello\");    // s comes into scope\n  takes_ownership(s);               // s's value moves into the function\n                                    // s is no longer valid\n\n  let x = 5;                        // x comes into scope\n\n  makes_copy(x);                    // x would move into the function\n                                    // but i32 is Copy, so it's ok to use x afterward\n}\n\nfn takes_ownership(some_string: String) { // some_string comes into scope\n  println!(\"{}\", some_string);\n} // some_string goes out of scope and `drop`, `the backing memory is freed`\n\nfn makes_copy(some_integer: i32) { // some_integer comes into scope\n  println!(\"{}\", some_integer);\n} // some_integer goes out of scope. `Nothing special happens.`\n```\n\n### Return Values and Scope\n\n- Returning values can also transfer ownership\n\n```rust\nfn main() {\n  let s1 = gives_ownership();               // gives_ownership moves its return value into s1\n\n  let s2 = String::from(\"hello\");           // s2 comes into scope\n\n  let s3 = takes_and_gives_back(s2);        // s2 is moved into takes_and_gives_back\n                                            // takes_and_gives_back moves its return value into s3\n} // s3 goes out of scope, and is dropped\n  // s2 goes out of scope, but was moved, so nothing happens\n  // s1 goes out of scope, and it dropped\n\nfn gives_ownership() -\u003e String {            // gives_ownership will move its return value into the function that calls it\n  let some_string = String::from(\"hello\");  // some_string comes into scope\n\n  some_string                               // some_string is returned and moves out to the calling function\n}\n\nfn takes_and_givs_back(a_string: String) -\u003e String { // a_string comes into scope\n  a_string                                           // a_string is returned and moves out to the calling function\n}\n```\n\n- The ownership of a variable follows the same pattern every time\n  - Assigning a value to another variable moves it. When a variable that includes data on the heap goes out of scope\n  - The value will be cleaned up by drop unless ownership of the data has been moved to another variable.\n\n### Returning with Tuple\n\n```rust\nfn main() {\n  let s1 = String::from(\"hello\");\n\n  let (s2, len) = calculate_length(s1);\n\n  println!(\"The length of '{}' is {}.\", s2, len);\n}\n\nfn calculate_length(s: String) -\u003e (String, usize) {\n  let length = s.len();\n\n  (s, length)\n}\n```\n\n## References and Borrowing\n\n```rust\nfn main() {\n  let s1 = String::from(\"hello\");         // s1 will not be dropped when the reference goes out of scope\n\n  let len = calculate_length(\u0026s1);        // s1 still have ownership because provide its as reference\n\n  println!(\"{}, {}\", s1, len);            // the tuple is stil valid\n}\n\nfn calulate_length(s: \u0026String) -\u003e usize { // s is a reference\n  s.len()\n} // goes out of scope, it refer to, it is not dropped because s doesn't have ownership\n```\n\n### Mutable References\n\n```rust\nfn main() {\n  let mut s = String::from(\"hello\");\n\n  change(\u0026mut s);                        // updatable reference\n  cannot_change(\u0026s);\n}\n\nfn canot_change(some_string: \u0026String) {  // cannot borrow immutable borrowed content\n  some_string.push_ptr(\", world\"); // ERROR!\n}\n\nfn change(some_string: \u0026mut String) {\n  some_string.push_ptr(\", world\");\n}\n```\n\n#### Mutable refernces restriction\n\nyou can only have `one mutable reference` to a particular piece of data in particular scope. The benefit of having this restriction is that Rust can prevent data races at compile time. This code will fail:\n\n```rust\nlet mut s = String:from(\"hello\");\n\nlet r1 = \u0026mut s;\nlet r2 = \u0026mut s;                        // s cannot be borrowed more than once at a time\n\nprintln!(\"{}, {}\", r1, r2);             // first borrow later used here\n```\n\n#### Multiple mutable refernes by creating a new scope\n\n```rust\nlet mut s = String:from(\"hello\");\n\n{\n  let r1 = \u0026mut s;\n} // r1 goes out of scope here, now we can make a new reference\n\nlet r2 = \u0026mut s;\n```\n\n#### Immutable references\n\nCannot have a mutable reference while we have an immutable one.\n\n```rust\nlet mut s = String::from(\"hello\");\n\nlet r1 = \u0026s; // no problem, immutable borrow occurs here\nlet r2 = \u0026s; // no problem\nlet r3 = \u0026mut s; // ERROR, mutable borrow occurs here\n```\n\nThese scopes don’t overlap, so this code is allowed.\n\n```rust\nlet mut s = String::from(\"hello\");\n\nlet r1 = \u0026s; // no problem\nlet r2 = \u0026s; // no problem\nprintln!(\"{} and {}\", r1, r2);\n// variables r1 and r2 will not be used after this point\n\nlet r3 = \u0026mut s; // no problem\nprintln!(\"{}\", r3);\n```\n### Dangling References\n\n\u003e dangling pointer—a pointer that references a location in memory that may have been given to someone else\n\nIn Rust, the compiler guarantees that references will never be dangling reference\n\n```rust\nfn main() {\n  let reference_to_nothing = dangle();\n}\n\nfn dangle() -\u003e \u0026String { // dangle returns a reference to a String\n  let s = String::from(\"hello\"); // s is a new String in dangle\n\n  \u0026s // ERROR! missing lifetime specifier\n} // s goes out of scope, and is dropped. It's memory goes away\n\nfn no_dangle() -\u003e String {\n  let s = String::from(\"hello\");\n\n  s\n}\n```\n\n## The Slice Type\n\n- Slice let you reference a contiguous sequence of elements in a colleaction rather than the whole collection\n- Slice doesn't have ownership\n\n```rust\nfn first_word(s: \u0026String) -\u003e usize {\n  let bytes = s.as_bytes();\n\n  // use reference\n  for (i, \u0026item) in bytes.iter().enumerate() {\n    if item == b' ' {\n      return i;\n    }\n  }\n\n  s.len()\n}\n\nfn main() {\n  let mut s = String::from(\"hello world\");\n\n  let word = first_word(\u0026s); // word will get the value 5\n\n  s.clear(); // empties the String, making it euqal to \"\"\n\n  // word still has the value 5 here, but there's no more string that\n  // we could meaningfully use the value 5 with. word is now totally invalid!\n}\n```\n\n### String Slices\n\n- String slice is a `reference` to part of a String\n\n```rust\nlet s = String::from(\"hello\");\n\n// with ..\nlet slice = \u0026s[0..2];  // =\u003e hel\nlet slice = \u0026s[..2];   // =\u003e hel\n\n// drop the trailing number\nlet let = s.len();\n\nlet slice = \u0026s[3..len]; // =\u003e o\nlet slice = \u0026s[3..];    // =\u003e o\n\n// both drop\nlet slice = \u0026s[0..len]; // =\u003e hello\nlet slice = \u0026s[..];     // =\u003e hello\n```\n\n- Rewrite of `first_word`\n\n```rust\nfn first_word(s: \u0026String) -\u003e \u0026str {\n  let bytes = s.as_bytes();\n\n  for (i, \u0026item) in bytes.iter().enumerate() {\n    if (item == b' ') {\n      return \u0026s[0..i];\n    }\n  }\n\n  \u0026s[..]\n}\n\n// If we have an immutable reference to something, we `cannot` also take a mutable reference\nfn main() {\n    let mut s = String::from(\"hello world\");\n\n    let word = first_word(\u0026s); // immutable borrow occurs here\n\n    s.clear(); // error!, mutable borrow occrus here\n\n    println!(\"the first word is: {}\", word); // word is still used here\n}\n```\n\n#### String literals are slices\n\nString literals being stored inside the binary.\n\n```rust\nlet s = \"Hello, world!\"; // s is \u0026str, slice pointing, immutable reference\n```\n\n#### String Slices as Paramters\n\nWe can pass string slice directly or slice of the entire String\n\n```rust\nfn first_word(s: \u0026str) -\u003e \u0026str { // support \u0026String and \u0026str (deref)\n  ...\n}\n\nfn main() {\n  let my_string = String::from(\"hello world\");\n\n  // `first_word` works on slices of `String`s, whether partial or whole\n  let word = first_word(\u0026my_string[0..6]);\n  let word = first_word(\u0026my_string[..]);\n  // `first_word` also works on references to `String`s, which are equivalent\n  // to whole slices of `String`s\n  let word = first_word(\u0026my_string);\n\n  let my_string_literal = \"hello world\";\n\n  // `first_word` works on slices of string literals, whether partial or whole\n  let word = first_word(\u0026my_string_literal[0..6]);\n  let word = first_word(\u0026my_string_literal[..]);\n\n  // Because string literals *are* string slices already,\n  // this works too, without the slice syntax!\n  let word = first_word(my_string_literal);\n}\n```\n\n#### Other slices\n\nThe slice has the type `\u0026[i32]`, works the same way as string slice do\n\n```rust\nlet a = [1, 2, 3, 4, 5];\nlet slice = \u0026a[1..3];\n```\n\n# Using Structs to Structre Related Data\n\n\u003e Structure, is a custom data type that lets you package together and name multiple related values that make up a meaningful group\n\n## Defining and Instantiation Structs\n\n- The pieces of a struct can be different type, can be named\n\n```rust\nstruct User {\n  username: String,\n  email: String,\n  sign_in_count: u64,\n  active: bool\n}\n```\n\n- Create an instance by specifying concreat values\n\n```rust\nlet user1 = User {\n  email: String::from(\"someone@example.com\"),\n  username: String::from(\"someone\"),\n  active: true,\n  sign_in_count: 1,\n}\n```\n\n- Get value with `dot notation`. it the instance is mutable, we can change a value by using the dot notation\n- Certain field as mutable is not allowed\n\n```rust\nlet mut user1 = User {\n  email: String::from(\"someone@example.com\"),\n  username: String::from(\"someone\"),\n  active: true,\n  sign_in_count: 1,\n}\n\nuser1.email = String::from(\"someone@example.com\");\n```\n\n- Using builder function\n\n```rust\n// implicity return that new instance\n\nfn build_user(email: String, username: String) -\u003e User {\n  User {\n    email: email,\n    username: username,\n    active: true,\n    sign_in_count: 1,\n  }\n}\n```\n\n### Using the Field Init Shorthand\n\n```rust\nfn build_user(email: String, username: String) -\u003e User {\n  email, // no repetition\n  username,\n  active: true,\n  sign_in_count: 1,\n}\n```\n\n### Creating instances from other instnace with update value, or struct update syntax\n\n```rust\n// without update syntax\nlet user2 = User {\n  email: String::from(\"another@example.com\"),\n  username: String::from(\"another\"),\n  active: user1.active,\n  sign_in_count: user1.sign_in_count\n};\n\n// using struct update syntax `..`\nlet user2 = User {\n  email: String::from(\"another@example.com\"),\n  username: String::from(\"another\"),\n  ..user1\n}\n```\n\n### Using Tuple Structs Without Named Fields to Create Different Types\n\n```rust\nstruct Color(i32, i32, i32); // Tuple structs\nstruct Point(i32, i32, i32);\n\nlet black = Color(0, 0, 0);\nlet origin = Point(0, 0, 0);\n```\n\n### Unit-like Structs without Any Field\n\n```rust\nstruct AlwaysEqual;\n\nfn main() {\n  let subject = AlwaysEqual;\n}\n```\n\n## An Example Program Using Struct\n\n```rust\n// sample code with multiple arguments\nfn area(width: u32, height: u32) -\u003e u32 {\n  width * height\n}\n\narea(width, height);\n```\n\n### Refactoring with Tuples\n\n```rust\nfn area(dimensions: (u32, u32)) -\u003e u32 {\n  return dimensions.0 * dimensions.1\n}\n\narea((30, 50));\n```\n\n### Refactoring with Structs: Adding More Meaning\n\n```rust\n// with struct\nstruct Rectangle {\n  width: u32,\n  height: u32\n}\n\nfn area(rectangle: \u0026Rectangle) -\u003e u32 {\n  rectangle.width * rectangle.height\n}\n\nlet rect = Rectangle { width: 30, height: 50 };\n\narea(\u0026rect);\n```\n\n### Adding Useful Functionality with Derived Traits\n\n```rust\n#[derive(Debug)] // define outer attribute\nstruct Rectangle {\n  width: u32,\n  height: u32,\n}\n\nfn main() {\n  let rect1 = Rectangle { width: 30, height: 50 };\n  println!(\"rect 1 is {:?}\", rect1); // {} doesn't work because of lack of Display implement\n\n\n  let rect2 = Rectangle {\n    width: dbg!(30 * scale),  // dbg! macro to prints the stderr\n    height: 50\n  };\n\n  dbg!(\u0026rect2);\n}\n```\n\n## Method Syntax\n\n\u003e Methods are similar to functions, methods are different from functions in that they're defined within the context of a struct\n\n### Defining Methods\n\n```rust\n#[derive(Debug)]\nstruct Rectangle {\n  width: u32,\n  height: u32,\n}\n\n// starts with impl\nimpl Rectangle {\n  // \u0026self instead of rectangle: \u0026Rectangle\n  // `\u0026mut self`, to take an ownership\n  fn area(\u0026self) -\u003e u32 {\n    self.width * self.height\n  }\n\n  // same name as one of the struct's fields\n  fn width(\u0026self) -\u003e bool {\n    self.width \u003e 0\n  }\n}\n\nfn main() {\n  let rect1 = Rectangle { width: 30, height: 50 };\n  println!(\n    \"The area of the rectangle is {} square pixels.\",\n    rect1.area()\n  )\n}\n```\n\n### Where’s the -\u003e Operator?\n\n```rust\n// Rust has a feature called automatic referencing and dereferencing, automatically adds in `\u0026, \u0026mut or *` instead of using `-\u003e`. following are same\np1.distance(\u0026p2);\n(\u0026p1).distance(\u0026p2);\n```\n\n### Methods with More Parameters\n\n```rust\nimpl Rectangle {\n  fn area(\u0026self) -\u003e u32 {...}\n  fn can_hold(\u0026self, other: \u0026Rectangle) -\u003e bool {\n    self.width \u003e other.width \u0026\u0026 self.height \u003e other.height\n  }\n}\n\n...\n\nrect1.can_hold(\u0026rect2);\n```\n\n### Associated Functions\n\n```rust\nimpl Rectangle {\n  // Assoociated functions, without `self` parameter, still functions, not methods\n  fn square(size: u32) -\u003e Rectangle {\n    // Often used for constructor that will return a new instance of the struct\n    Rectangle { width: size, height: size }\n  }\n}\n\nlet sq = Rectangle::square(3);\n```\n\n### Multiple impl Blocks\n\n```rust\nimpl Rectangle {\n  fn area(\u0026self) -\u003e u32 {\n    self.width * self.height\n  }\n}\n\nimpl Rectangle {\n  fn can_hold(\u0026self, other: \u0026Rectangle) -\u003e bool {\n    self.width \u003e other.width \u0026\u0026 self.height \u003e other.height\n  }\n}\n```\n\n# Enums and Pattern Matching\n\n## Defining an Enum\n\n````rust\n// define enum without type\nenum IpAddrKind {\n  V4,\n  V6,\n}\n\nlet four = IpAddrKind::V4;\nlet six = IpAddrKind::V6;\n\nfn route(ip_type: IpAddrKind) {...}\n\nstruct IpAddr {\n  kind: IpADdrKind,\n  address: String,\n}\n\nlet home = IpAddr {\n  kind: IpAddrKind::V4,\n  address: String::from(\"127.0.0.1\"),\n}\n\nlet loopback = IpAddr {\n  kind: IpAddrKind::V6,\n  address: String::from(\"::1\"),\n}\n\n// define enum value associated String\nenum IpAddr {\n  V4(String),\n  V6(String),\n}\n\nlet home = IpAddr::V4(String::From(\"127.0.0.1\"));\nlet loopback = IpAddr::V6(String::From(\"::1\"));\n\n// define enum with different types and amounts of associated data\nenum IpAddr {\n  V4(u8, u8, u8, u8),\n  V6(String),\n}\n\nlet home = IpAddr::V4(String::From(127, 0, 0, 1));\nlet loopback = IpAddr::V6(String::From(\"::1\"));\n\n// define enum embedded struct as associated type\nstruct Ipv4Addr {\n  ...\n}\n\nstruct Ipv6Addr {\n  ...\n}\n\nenum IpAddr {\n  V4(Ipv4Addr),\n  V6(Ipv6Addr)\n}\n\n// define enum with variant\nenum Message {\n  Quit,\n  Move { x:i32, y: i32 },\n  Write(String),\n  ChangeColor(i32, i32, i32)\n}\n\n// define method using impl\nimpl Message {\n  fn call(\u0026self) {\n    ...\n  }\n}\n\nlet m = Message.Write(String::from(\"hello\"));\nm.call();\n````\n\n## The `Option` Enum and Its Advantages Over Null Values\n\n- Rust does not have nulls, but it does have an enum that being present of absent\n- Another enum, compiler can check whether you've handled all the cases\n- Option\u003cT\u003e is defined by the standard library\n- Option value, `Some`, contains a value, or `None`, does not\n\n```rust\n// Option is defined by the standard libaray, included in the prelude\nenum Option\u003cT\u003e {\n  None,\n  Some(T),\n}\n\n// hold number type\nlet some_number = Some(5);\n\n// hold string type\nlet some_string = Some(\"a string\")\n\n// hold none value\nlet absent_number: Option\u003ci32\u003e = None;\n\nlet x: i8 = 5;\nlet y: Options\u003ci8\u003e = Some(5);\n\nlet sum = x + y; // error, they are different type, i8 + std::option:Option\u003ci8\u003e\n```\n\n### [Use Some Value with various method](https://doc.rust-lang.org/std/option/enum.Option.html)\n\n```rust\nlet mut x = Some(2);\n\nmatch x.as_mut() {\n    Some(v) =\u003e *v = 42, // matched\n    None =\u003e {},\n}\n\nassert_eq!(x, Some(42)); // valid\n\nlet x = Some(\"value\");\nassert_eq!(x.expect(\"the world is ending\"), \"value\"); // valid, expect return some value, but if some value is None? panics with \"the world is ending\"\n\nlet x: Option\u003cu32\u003e = Some(2);\nassert_eq!(x.is_some(), true); // valid\n\nlet x: Option\u003cu32\u003e = None;\nassert_eq!(x.is_some(), false); // valid\n\nlet x: Option\u003cu32\u003e = Some(2);\nassert_eq!(x.is_none(), false); // valid\n\nlet x: Option\u003cu32\u003e = None;\nassert_eq!(x.is_none(), true); // valid\n```\n\n### Some Value usecases\n\n```rust\nfn divide(numerator: f64, denominator: f64) -\u003e Option\u003cf64\u003e {\n    if denominator == 0.0 {\n        None\n    } else {\n        Some(numerator / denominator)\n    }\n}\n\n// The return value of the function is an option\nlet result = divide(2.0, 3.0);\n\n// Pattern match to retrieve the value\nmatch result {\n    // The division was valid\n    Some(x) =\u003e println!(\"Result: {}\", x), // 0.6666666666666666\n    // The division was invalid\n    None    =\u003e println!(\"Cannot divide by 0\"),\n}\n```\n\n## The `match` Control Flow Operator\n\n- Basic usese\n\n```rust\nenum Coin {\n    Penny,\n    Nickel,\n    Dime,\n    Quarter,\n}\n\nfn value_in_cents(coin: Coin) -\u003e u8 {\n    match coin {\n        Coin::Penny =\u003e 1,\n        Coin::Nickel =\u003e 5,\n        Coin::Dime =\u003e 10,\n        Coin::Quarter =\u003e 25,\n    }\n}\n```\n\n- Run multiple lines of code in a match arm\n\n```rust\nfn value_in_cents(coin: Coin) -\u003e u8 {\n    match coin {\n        Coin::Penny =\u003e {\n           println!(\"Lucky penny!\");\n            1\n        }\n        Coin::Nickel =\u003e 5,\n        Coin::Dime =\u003e 10,\n        Coin::Quarter =\u003e 25,\n    }\n}\n```\n\n### Patterns That Bind to Values\n\n```rust\n#[derive(Debug)] // so we can inspect the state in a minute\nenum UsState {\n  Alabama,\n  Alaska,\n  // --snip--\n}\n\nenum Coin {\n  Penny,\n  Nickel,\n  Dime,\n  Quarter(UsState),\n}\n\nfn value_in_cents(coin: Coin) -\u003e u32 {\n  match coin {\n    // match enum and return function\n    Coin::Peny =\u003e {\n      println!(\"Lucky penny!\");\n      1\n    }\n    // match enum and return value\n    Coin::Nickel =\u003e 5,\n    Coin::Dime =\u003e 10,\n    // patterns that bind to values, value_in_cents(Coin::Quarter(UsState::Alaska))\n    Coin::Quater(state) =\u003e {\n      println(\"State quater from{:?}!\", state);\n      25\n    },\n  }\n}\n```\n\n### Matching with `Option\u003cT\u003e`\n\n```rust\nfn plus_one(x: Option\u003ci32\u003e) -\u003e Option\u003ci32\u003e {\n  match x {\n    None =\u003e None,\n    Some(i) =\u003e Some(i + 1),\n  }\n}\n\nlet five = Some(5);\nlet six = plus_one(five); // returns 6\nlet none = plus_one(None); // No value to add to, stops and return `None`\n```\n\n### Matches Are Exhaustive\n\nThe arms’ patterns must cover all possibilities\n\n```rust\nfn plus_one(x: Option\u003ci32\u003e) -\u003e Option\u003ci32\u003e {\n  match x {\n    Some(i) =\u003e Some(i + 1), // Error, didn't cover every possible case, `Pattern 'None` not covered\n  }\n}\n```\n\n### Catch-all Patterns and the _ Placeholder\n\nUse this when we don't want to list all possible values. `_` pattern will match any value.\n\n```rust\nlet dice_roll = 9;\nmatch dice_roll {\n    3 =\u003e add_fancy_hat(),\n    7 =\u003e remove_fancy_hat(),\n    _ =\u003e reroll(),cases\n}\n\nfn add_fancy_hat() {}\nfn remove_fancy_hat() {}\nfn reroll() {} \n}\n```\n\nWe can express that by using the empty tuple type as the code that goes with the _ arm\n\n```rust\nlet dice_roll = 9;\nmatch dice_roll {\n    3 =\u003e add_fancy_hat(),\n    7 =\u003e remove_fancy_hat(),\n    _ =\u003e (),\n}\n\nfn add_fancy_hat() {}\nfn remove_fancy_hat() {}\n```\n\n## Concise Control FLow with `if let`\n\n- `if let` syntax lets you combine `if` and `let` into a less verbos way to handle value that match one pattern while ignoring the rest\n\n### Match one pattern\n\n`if let` is `syntax sugar` for a match that runs code when the value matches one pattern\n\n```rust\nlet some_u8_value = Some(0u8);\nmatch some_u8_value {\n  Some(3) =\u003e println!(\"three\"),\n  _ =\u003e (),\n}\n\n// only work woth Some(3), using if let instead of\n\nif let Some(3) = some_u8_value {\n  println!(\"three\");\n}\n```\n\n### With else\n\n```rust\nfn main() {\n  let mut count = 0;\n  if let Coin::Quater(state) = coin {\n    println!(\"State quater from {:?}!\", state);\n  } else {\n    count + 1;\n  }\n}\n```\n\n# Managing Growing Projects with Packages, Crates, and Modules\n\nAs you write large programs, organizing your code will become increasingly important. By grouping related functionality and separating code with distinct features, you’ll clarify where to find code that implements a particular feature and where to go to change how a feature works.\n\n- Packages: A Cargo feature that let you build, test, and share crates\n- Crates: A tree of modules that produce a library or executable\n- Modules and the use: Let you control the organization, scope, and privacy of path\n- Paths: A way of naming an item such as a struct function, or module\n\n## Packages and Crates\n\n- crate: smallest amount of code that Rust compiler consider at a time\n  - binary crate:\n  - programs you can compile to an executable that you can run\n  - library crate:\n  - don't have main\n  - don't compile to an executable\n  - shared with multiple pojects\n  - Rustaceans says `crate`, they mean library crate\n- package: a bundle of one or more crates that provides a set of functionality\n  - contains a Cargo.toml that describe how to build one or more crates\n  - Cargo, is binary crate for build, also contgains a library crate\n  - can contain as many binary crate\n  - must contain at least one crate\n\n```rust\n// package\n.\n├── Cargo.toml\n├── bin // package can have multiple binary crates\n└── src\n    ├── lib.rs // crate root, it can be library or binary\n    └── main.rs // crate root, it can be binary\n```\n\n## Defining Modules to Control Scope and Privacy\n\n### Modules Cheat Sheet\n\n- How module work\n  - Start from the crate root: when compiling a crate, the compiler first looks in the crate root file `src/main.rs` or `src/lib.rs`\n  - Declaring modules: as `mod garden` declared, the compiler will look for module's code in these places: Inline \u003e `src/garden.rs` \u003e `src/garden/mod.rs`\n  - Declaring submodules: as `mod vegetables` decalred in `src/garden.rs`, the compiler will look for the submodule's code within the directory named for the parent module in these places: Inline \u003e `src/garden/vegetables.rs` \u003e `src/garden/vegetables/mod.rs`\n  - Plath to code in modules: Once a module is part of your crate, you can refer to code. For example, `Asparagus` type in the garden vegetable module would be found at `crate::garden::vegetables::Asparagus`\n  - Private vs Public: Private from its parent modules by default, use `pub mod` to make a module public\n  - The use keyword: Within a scope, the `use` keyword creates shortcuts to item to reduce repetion of long paths. `use crate::garden::vegetables::Asparagus;` make you only need to write just `Asparagus`\n- The crate’s directory, also named backyard, contains these files and directories:\n\n```rust\nbackyard\n├── Cargo.lock\n├── Cargo.toml\n└── src\n    ├── garden\n    │   └── vegetables.rs\n    ├── garden.rs\n    └── main.rs\n```\n\n- The crate root file in this case is src/main.rs, and it contains:\n\n```rust\nuse crate::garden::vegetables::Asparagus;\n\npub mod garden;\n\nfn main() {\n    let plant = Asparagus {};\n    println!(\"I'm growing {:?}!\", plant);\n}\n```\n\n- The `pub mod garden;` line tells the compiler to include the code it finds in `src/garden.rs`\n\n\n```rust\npub mod vegetables;\n```\n\n- `pub mod vegetables;` means the code in `src/garden/vegetables.rs` is included too\n\n```rust\n#[derive(Debug)]\npub struct Asparagus {}\n```\n\n### Grouping Related Code in Modules\n\n```rust\nmod front_of_house {\n  mod hosting {\n    fn add_to_waitlist() {}\n    fn seat_at_table() {}\n  }\n\n  mod serving {\n    fn take_order() {}\n    fn server_order() {}\n    fn take_payment() {}\n  }\n}\n```\n\nhere is `module tree`. `src/main.rs` and `src/lib.rs` are called crate roots\n\n```\ncrate\n └── front_of_house\n     ├── hosting\n     │   ├── add_to_waitlist\n     │   └── seat_at_table\n     └── serving\n         ├── take_order\n         ├── serve_order\n         └── take_payment\n```\n\n### Paths for Referring to an Item in the Module Tree\n\n- `An absolute path` is the full path starting from a crate root; for code from an external crate, the absolute path begins with the crate name, and for code from the current crate, it starts with the literal crate.\n- `A relative path` starts from the current module and uses self, super, or an identifier in the current module.\n- Both absolute and relative paths are followed by one or more identifiers separated by double colons `(::)`\n\n```rust\nmod front_of_house {\n  mod hosting {\n      fn add_to_waitlist() {}\n  }\n}\n\npub fn eat_at_restaurant() {\n  // Absolute path\n  crate::front_of_house::hosting::add_to_waitlist(); // error, module `hosting` is private\n\n  // Relative path\n  front_of_house::hosting::add_to_waitlist();\n}\n```\n\n- Module are the privacy boundary in Rust\n- All items (functions, methods, structs, enums, modules and constants) are private by default\n- `pub` keyword to make an item public\n- Items in a parent module `can’t use` the private items `inside child modules`, but items in child modules `can us`e the items in `their ancestor modules`.\n\n```rust\nmod front_of_house {\n  pub mod hosting {\n    pub fn add_to_waitlist() {}\n  }\n}\n\npub fn eat_at_restaurant() {\n  // Absolute path\n  crate::front_of_house::hosting::add_to_waitlist(); \n\n  // Relative path\n  front_of_house::hosting::add_to_waitlist();\n}\n```\n\n### Starting Relative Paths with `super`\n\n- `super`, is like starting a file system path with `...`\n- in case of `super` is root\n\n```rust\nfn deliver_order() {}\n\nmod back_of_house {\n  fn fix_incorrect_order() {\n    cook_order();\n    super::deliver_order();\n  }\n\n  fn cook_order() {}\n}\n```\n\n### Making Structs and Enums Public\n\n- `pub` before a struct definition, we make the struct public\n\n```rust\nmod back_of_house {\n  // pub to make public struct\n  pub struct Breakfast {\n    pub toast: String,\n    seasonal_fruit: String,\n  }\n\n  impl Breakfast {\n    // If Breakfast didn’t have such a function, we couldn’t create an instance of\n    // Breakfast in eat_at_restaurant because we couldn’t set the value of the private\n    // seasonal_fruit field in eat_at_restaurant.\n    pub fn summer(toast: \u0026str) -\u003e Breakfast {\n      Breakfast {\n        toast: String::from(toast),\n        seasonal_fruit: String::from(\"peaches\"),\n      }\n    }\n  }\n}\n\npub fn eat_at_restaurant() {\n  // Order a breakfast in the summer with Rye toast\n  let mut meal = back_of_house::Breakfast::summer(\"Rye\");\n  // Change our mind about what bread we'd like\n  meal.toast = String::from(\"Wheat\");\n  println!(\"I'd like {} toast please\", meal.toast);\n\n  // The next line won't compile if we uncomment it; we're not allowed\n  // to see or modify the seasonal fruit that comes with the meal\n  // meal.seasonal_fruit = String::from(\"blueberries\");\n}\n```\n\n- if we make an enum public, all of its variants are then public\n\n```rust\nmod menu {\n  pub enum Appetizer {\n    Soup,\n    Salad,\n  }\n}\n\nfn main() {\n  let order1 = menu::Appetizer::Soup;\n  let order2 = menu::Appetizer::Salad;\n}\n```\n\n## Bringing Paths into Scope with the use Keyword\n\n- Create a shortcut to a path with the `use` keyword once, and then use the shorter name everywhere else in the scope\n- Adding use and a path in a scope is similar to creating a symbolic link in the filesystem. By adding use crate::front_of_house::hosting in the crate root, hosting is now a valid name in that scope\n\n```rust\nmod front_of_house {\n  pub mod hosting {\n      pub fn add_to_waitlist() {}\n  }\n}\n\nuse crate::front_of_house::hosting;\n\npub fn eat_at_restaurant() {\n  hosting::add_to_waitlist();\n}\n```\n\n- `use` only creates the shortcut for the particular scope in which the `use` occurs\n\n```rust\nmod front_of_house {\n  pub mod hosting {\n    pub fn add_to_waitlist() {}\n  }\n}\n\nuse crate::front_of_house::hosting;\n\nmod customer {\n  pub fn eat_at_restaurant() {\n    hosting::add_to_waitlist(); // error, failed to resolve: use of undeclared crate or module `hosting`\n  }\n}\n```\n\n### Creating Idiomatic use Paths\n\n- Specifying the parent module when calling the function makes it clear that the function isn’t locally defined\n\n```rust\nmod front_of_house {\n  pub mod hosting {\n      pub fn add_to_waitlist() {}\n  }\n}\n\nuse crate::front_of_house::hosting::add_to_waitlist; // make it confusing between local defined function\n\npub fn eat_at_restaurant() {\n  add_to_waitlist();\n}\n```\n\n- On the other hand, when bringing in structs, enums, and other items with use, it’s idiomatic to specify the full path\n\n```rust\nuse std::collections::HashMap;\n\nfn main() {\n    let mut map = HashMap::new();\n    map.insert(1, 2);\n}\n```\n\n- There’s no strong reason behind this idiom: it’s just the convention that has emerged, and folks have gotten used to reading and writing Rust code this way.\n- If we’re bringing two items with the same name into scope with use statements, because Rust doesn’t allow that\n\n```rust\nuse std::fmt;\nuse std::io;\n\nfn function1() -\u003e fmt::Result {\n    // --snip--\n}\n\nfn function2() -\u003e io::Result\u003c()\u003e {\n    // --snip--\n}\n```\n\n### Providing New Names with the as Keyword\n\n- Same name into the same scope with use: after the path, we can specify as and a new local name, or alias, for the type\n\n```rust\nuse std::fmt::Result;\nuse std::io::Result as IoResult;\n\nfn function1() -\u003e Result {\n    // --snip--\n}\n\nfn function2() -\u003e IoResult\u003c()\u003e {\n    // --snip--\n}\n```\n\n### Re-exporting Names with pub use\n\n- Bring a name into scope with the use keyword, the name available in the new scope is private.\n- To `re-exporting`, combine `pub` and `use`\n\n```rust\nmod front_of_house {\n    pub mod hosting {\n        pub fn add_to_waitlist() {}\n    }\n}\n\npub use crate::front_of_house::hosting;\n\npub fn eat_at_restaurant() {\n    hosting::add_to_waitlist();\n}\n```\n\n### Using External Packages\n\n- Add package to `Cargo.toml` we want to use. for example `rand`. \n- Cargo will down load `rand` package\n- Any dependencies from crates.io and make rand available to our project.\n\n```toml\nrand = \"0.8.5\"\n```\n\n- Use line starting with the name of the crate, rand, and listed the items we wanted to bring into scope\n\n```rust\nuse rand::Rng;\n\nfn main() {\n    let secret_number = rand::thread_rng().gen_range(1..=100);\n}\n```\n\n- Standard std library is also a crate that’s external to our package.\n- Because the standard library is shipped with the Rust language, we don’t need to change Cargo.toml to include std\n- But we do need to refer to it with `use` to bring items from there into our package’s scope\n\n```rust\nuse std::collections::HashMap;\n```\n\n### Using Nested Paths to Clean Up Large use Lists\n\n- Use curly brackets after two colons to bring the same items into scope in one line. \n\n```rust\nuse std::cmp::Ordering;\nuse std::io;\n\n// use ::{,} to bring itmes\nuse std::{cmp::Ordering, io};\n```\n\n- We can use a nested path at any level in a path, which is useful when combining two use statements that share a subpath\n\n```rust\nuse std::io;\nuse std::io::Write;\n\n// use `self` in the nested path\nuse std::{self, Write}\n```\n\n### The Glob Operator\n\n- To bring all public items defined in a path into scope\n\n```rust\nuse std::collections::*;\n```\n\n## Separating Modules into Different Files\n\n- We’ll extract modules into files instead of having all the modules defined in the crate root file. see below\n\n```\nsrc\n └── lib.rs\n └── front_of_house\n     └── hosting.rs\n```\n\n- `src/lib.rs` decalre `mod front_of_house` at the begin of the file\n\n```rust\nmod front_of_house;\n\npub use crate::front_of_house::hosting;\n\npub fn eat_at_restaurant() {\n  hosting::add_to_waitlist();\n}\n```\n\n- `src/front_of_house.rs` decalre `mod hositing` and makes it as public\n\n```rust\npub mod hosting;\n```\n\n- `src/front_of_house/hosting.rs` contains the definitions\n\n```rust\npub fn add_to_waitlist() {}\n```\n\n- alternate File Paths\n  - src/front_of_house.rs (what we covered)\n  - src/front_of_house/mod.rs (`older style`, still supported path)\n\n# Common Collections\n\nRust’s standard library includes a number of very useful data structures called collections. Collections can contain multiple values. Unlike the built-in array and tuple types\n\n- vector: allows you to store a variable number of values next to each other\n- string: collection of characters\n- hash map: allows you to associate a value with a particular key\n\n## Storing Lists of Values with Vectors\n\n### Creating a New Vector\n\n\u003e [samples](./5-collections/src/main.rs)\n\n```rust\nlet v: Vec\u003ci32\u003e = Vec::new(); // added a type annotation\n\nlet v = vec![1, 2, 3]; // use vec! macro\n```\n\n### Update a Vector\n\n```rust\nlet mut v = Vec::new();\n\nv.push(5);\nv.push(6);\nv.push(7);\nv.push(8);\n```\n\n### Reading Elements of Vectors\n\n- Two ways to reference a value. indexing[] and `get`\n- Out of index: [] will cause the panic, `get` method returns `None` without panicking\n\n```rust\nlet v = vec![1, 2, 3, 4, 5];\n\nlet third: \u0026i32 = \u0026v[2];\nprintln!(\"The third element is {third}\");\n\nlet third: Option\u003c\u002632\u003e = v.get(2);\nmatch third {\n  Some(third) =\u003e println!(\"The third element is {third}\");\n  None =\u003e println!(\"There is no thiid element.\");\n}\n```\n\n- Cannot have mutable and immutable references in the same scope\n\n```rust\nlet mut v = vec![1, 2, 3, 4];\nlet first = \u0026v[0]; // immutable borrow\nv.push(6); // mutable borrow, vector might require allocating new memory and copy the old elms\nprintln!(\"fist is {}\", first) // immutable borrow used here\n```\n\n### Iterating over the values in a Vector\n\n\u003e [samples](./5-collections/src/main.rs)\n\n```rust\nlet v = vec![100, 32, 57];\nfor i in \u0026v {\n  println!(\"{i}\");\n}\n\n// with mutable references\nlet mut v = vec![100, 32, 57];\nfor i in \u0026mut v {\n  *i + 50;  // use * dereference operator to get to the value\n}\n```\n\n### Using an enum to store multiple types\n\n- Vector can only store values that are the sample type. This can be inconvenient. To store different use enum\n- If you don’t know the exhaustive set of types a program, enum doesn't work, use Trait instead of\n\n```rust\n// this enum has multiple types\nenum SpreadsheetCell {\n  Int(32),\n  Float(f64),\n  Text(String)\n}\n\n// holds different types\nlet row = vec![\n  SpreadsheetCell::Int(3),\n  SpreadsheetCell::Text(String::from(\"blue\"))\n  SpreadsheetCell::Float(10.12)\n]\n```\n\n### Dropping a Vector Drops Its Elements\n\n- Vector is freed when it goes out of scope\n\n```rust\n{\n  let v = vec![1, 2, 3, 4];\n  // do stuff with v\n} // \u003c- v goes out of scope and is free here\n```\n\n## Storing UTF-8 Encoded Text With Strings\n\n### What Is a String?\n\n- String is only one type in the core language in Rust, `str`\n  - which is the string slice, usually seen in its borrowed\n- String are implemented as a collection of bytes\n- String, gowable, mutable, owned, UTF-8 encoded type\n\n### Creating a New String\n\n- Many of some operations available with Vec\u003cT\u003e\n- String is actually impemented as a wrapper around a vector of bytes with some extra gurantees restrictions and capbilities\n\n```rust\n// create a new empty string with the new function\nlet mut s = String::new();\n\n// create a string containing `string`\nlet data = \"initial contents\"\nlet s = data.to_string();\n\n// create a string from literal directly\nlet s = \"initial contents\".to_string();\n\n// create a string from a string literal same as to_string\nlet s = String::from(\"initial content\");\n```\n\n- Strings are UTF-8 encoded\n\n```rust\nlet hello = String::from(\"السلام عليكم\");\nlet hello = String::from(\"Dobrý den\");\nlet hello = String::from(\"Hello\");\nlet hello = String::from(\"שָׁלוֹם\");\nlet hello = String::from(\"नमस्ते\");\nlet hello = String::from(\"こんにちは\");\nlet hello = String::from(\"안녕하세요\");\nlet hello = String::from(\"你好\");\nlet hello = String::from(\"Olá\");\nlet hello = String::from(\"Здравствуйте\");\nlet hello = String::from(\"Hola\");\n```\n\n### Updading a String\n\n\u003e String can grow in size and its contents can change same as Vec\u003cT\u003e\n\n#### Appending to a String with push_str and push\n\n```rust\nlet mut s = String::from(\"foo\");\ns.push_str(\"bar\"); // method takes a string slice\n\nlet mut s1 = String::from(\"foo\");\nlet s2 = \"bar\";\ns1.push_str(s2); \nprintln!(\"s2 is {s2}\"); // s2 ownership still alive\n\n// single character\ns.push('l');\n```\n\n#### Concatenation with the + Operator or the format! Macro\n\n```rust\nlet s1 = String::from(\"Hello, \");\nlet s2 = String::from(\"world!\");\n\n// note s1 has been moved here and can no longer be used\nlet s3 = s1 + \u0026s2;  // 1. s1 will call `add(self, s:\u0026str) -\u003e String`\n                    // 2. \u0026s2 will be `deref coercion`, \u0026s2 -\u003e \u0026s2[..]\n                    // 3. `add` keep `s`'s ownership. s2  is still valid\n                    // 4. `add` takes ownership of self, s1 will be moved into the `add`\n                    // 5. s1 will no longer be valid after this operation\n                    // 6. append a copy of the content of s2\n                    // 7. return ownership of the result\n\n// format! for multiple concatenate\nlet s1 = String::from(\"tic\");\nlet s2 = String::from(\"tac\");\nlet s3 = String::from(\"toe\");\n\nlet s = format!(\"{}-{}-{}\", s1, s2, s3);\n```\n\n### Indexing into Strings\n\n- Rust doesn’t allow us to index into a String to get a character is that indexing\n\n```rust\n//  operations are expected to always take constant time (O(1)).\nlet s1 = String::from\nlet h = s1[0]; // `String` error cannot be indexed by {integer}\n```\n\n#### Internal Representation\n\n```rust\nlet hello = String::From(\"hola\").len(); // 4 byte, take 1 byte for UTF-8\nlet hello = String::from(\"Здравствуйте\").len(); // 24 byte, take 2 byte for UTF-8\nlet hello = \"Здравствуйте\";\nlet answer = \u0026hello[0]; // return 208 not '3', which is first byte\n```\n\n#### Bytes and Scalar Values and Grapheme Clusters! Oh My!\n\n- UTF-8 is that there are actually three relevant ways to look at strings from Rust’s perspective: as `bytes`, `scalar values`, and `grapheme clusters` (letters)\n- How “नमस्ते” (Devanagari scriptis) show in Rust's perspectives\n\n```rust\n// bytes (u8)\n[224, 164, 168, 224, 164, 174, 224, 164, 184, 224, 165, 141, 224, 164, 164, 224, 165, 135]\n\n// unicode scalar values (char, but 4 and 6 are not letters)\n['न', 'म', 'स', '्', 'त', 'े']\n\n// grapheme clusters, we'd get what a person would call the four `letters`\n[\"न\", \"म\", \"स्\", \"ते\"]\n```\n\n- Rust priovidess different ways of interpreting the raw string data which program can choose the interpretation it needs\n- Rust doesn't allow us to index into a string in constant time o(1) because Rust would  have to walk through the content from the begnning to the index to determine how many valid charaters there where\n\n### Slicing Strings\n\n- Rust asks you to be more specific via [] with a range to creat strin slice\n\n```rust\nlet hello = \"Здравствуйте\";\nlet s = \u0026hello[0..4]; // 4byte, will be Зд\nlet s = \u0026hello[0..1]; // panic, index is not a char boundary\n```\n\n### Methods for Iterating Over Strings\n\n- Use `chars` for individual Unicode scalar values\n\n```rust\nfor c in \"Зд\".chars() {\n  println!(\"{c}\");\n}\n\n// result\nЗ\nд\n\nfor c in \"Зд\".bytes() {\n  println!(\"{}\", c);\n}\n\n// result\n208\n151\n208\n180\n```\n\n### Strings Are Not So Simple\n\n- To Summarize, string are complicated. Different programming languages make different choices about how to present this complexity to the programmer\n- Rust has chosen to make the correct handling of String data the default behavior for all Rust programs, which means programmers have to put more thought into handling UTF-8 data upfront\n\n## Storing Keys with Assoicated Values in Hash Maps\n\n- `HashMap\u003cK, V\u003e` type stores a mapping of keys of type K to values of types V using `hashing function`\n- `Key` can be of any type\n\n### Creating a New Hash Map\n\n- Vector, Hash map store data on the heap\n- `insert` to add elements\n\n```rust\nuse std::collection::Hashmap;\n\nlet mut scores = HashMap::new();\n\nscores.insert(String::from(\"Blue\"), 10);\nscores.insert(String::from(\"Yellow\"), 50);\n```\n\n### Accessing Values in a Hash Map\n\n- `get` a value with `key`\n\n```rust\nuse std::collections::HashMap;\n\nlet mut scores = HashMap::new();\n\nscores.insert(String::from(\"Blue\"), 10);\nscores.insert(String::from(\"Yellow\"), 50);\n\nlet team_name = String::from(\"Blue\");\nlet score = scores\n  .get(\u0026team_name) // reutrn `Option(\u0026V)`, If no value?, will return `None`\n  .copied() // call `copied` to get Option\u003ci32\u003e rather than an Option\u003c\u0026i32\u003e\n  .unwrap_or(0); // set score to zero if scores doesn't have an entry\n```\n\n- using `for` loop\n\n```rust\nuse std::collections::HashMap;\n\nlet mut scores = HashMap::new();\n\nscores.inseret(String::from(\"Blue\"), 10);\nscores.inseret(String::from(\"Yellow\"), 50);\n\nfor (key, value) in \u0026scores {\n  println!(\"{key}: {value}\");\n}\n```\n\n### Hash Maps and Ownership\n\n- The values are copied into the hash map in case of types implemented the `Copy` trait, like i32\n- A string value, like String, will be moved and hash map will be the owner\n\n```rust\nlet field_name = String::from(\"Favorite color\");\nlet field_value = String::from(\"Blue\":);\n\nlet mut map = HashMap::new();\nmap.insert(field_name, filed_value); // values are copied into the hash\n                                     // field_name and field_value are invalid at this point, try using them and\n                                     // see what compiler error you get!\n```\n\n### Updating a Hash Map\n\n\u003e When you want to change the data in a hash map, you have to decide how to handle the case when a key already has a value assigned\n\n#### Overwriting a Value\n\n```rust\nuse std::collections::HashMap;\n\nlet mut scores = HashMap::new();\n\nscores.insert(String::from(\"Blue\"), 10);\nscores.insert(String::from(\"Blue\"), 25);\n\nprintln!(\"{:?}\", scores); \n\n// result\n{\"Blue\": 25}\n```\n\n#### Adding a Key and Value Only If a Key Isn’t Present\n\n```rust\nuse std::collections::HashMap;\n\nlet mut scores = HashMap::new();\nscores.insert(String::from(\"Blue\"), 10);\n\n// `or_insert` method on Entry is defined to return a mutable reference\nscores.entry(String::from(\"Yellow\")).or_insert(50);\nscores.entry(String::from(\"Blue\")).or_insert(50);\n\nprintln!(\"{:?}\", scores);\n\n// result\n{\"Yellow\": 50, \"Blue\": 10}\n```\n\n#### Updating a Value Based on the Old Value\n\n```rust\nuse std::collections::HashMap;\n\nlet text = \"hello world wonderful world\";\n\nlet mut map = HashMap::new();\n\nfor word in text.split_whitespace() {\n  let count = map.entry(word).or_insert(0);\n  *count += 1; // update old value\n}\n\nprintln!(\"{:?}\", scores);\n\n// result\n {\"world\": 2, \"hello\": 1, \"wonderful\": 1}\n```\n\n### Hashing Functions\n\n- Uses a hashing function called SipHash that can provide resistance to Denial of Service (DoS) attacks involving hash tables. This is not the fastest hashing algorithm available, but the trade-off for better security that comes with the drop in performance is worth it\n- You can switch to another function by specifying a different hasher. A hasher is a type that implements the BuildHasher trait\n\n# Errror Handling\n\n- Rust requires you to acknowledge the possibility of an error and take some action before your code will compile.\n- Rust group errors into two types of categories:\n  - recoverable: file not found error, Result\u003cT, E\u003e\n  - unrecoverable: symptoms of bugs, accessing end of an array, panic!\n- Rust doesn't have exceptions, manage Result\u003cT, E\u003e or get panic!\n\n## Unrecoverable Erros With panic!\n\n- When a panic occurs(or `panic!`), the program starts `unwinding` but it cleanup is a lot of work so Rust allow you to choose the alrernative of immediately aborting\n\n```\n[profile.release]\npanic = 'abort'\n```\n\n## Using a panic! Backtrace\n\n- Unlike C, Rust will stop execution and refuse to contitue in case of invalid index to protect your program from this sort of vulnerablity like `buffer overread`\n- To show backtrace, `RUST_BACKTRACE=1 cargo run`\n- To enable cargo symbol `cargo build, cargo run` without `--release`\n\n```rust\nfn main() {\n    let v = vec![1, 2, 3];\n\n    v[99];\n}\n```\n\n## Recoverable Error with Result\n\n- Opening file failed is that no need to terminate the process, we can create the file\n- Function returl `Result` because function could fail\n\n```rust\nenum Result\u003cT, E\u003e {\n  Ok(T),\n  Err(E),\n}\n```\n\n- When ssucceeds return Ok(T), failed, return Err(E)\n\n```rust\nuse std:fs::File;\n\nfn main() {\n  let f = File::open(\"hello.txt\");\n\n  let f = match f {\n    Ok(file) =\u003e file,\n    Err(error) =\u003e panic!(\"There was a problem opening file: {:?}\", error),\n  };\n}\n```\n\n### Matching on Different Errors\n\n- Take different actions for different failure reasons\n\n```rust\nuse std:fs::File;\n\nfn main() {\n  let f = File::open(\"hello.txt\");\n\n  let f = match f {\n    Ok(file) =\u003e file,\n    Err(error) =\u003e match error.kind() {\n      ErrorKind::NotFound =\u003e match File::create(\"hello.txt\") {\n        Ok(fc) = fc,\n        Err(e) = panic!(\"Tried to create file but there was a problem {:?}\", e),\n      },\n      other_error =\u003e panic!(\"There was a problem opening file: {:?}\", error)\n    },\n  };\n}\n```\n\n### Alternatives to Using match with Result\u003cT, E\u003e\n\n- Using closures and the `unwrap_or_else` without `match`\n\n```rust\nuse std::fs::File;\nuse std::io::ErrorKind;\n\nfn main() {\n  let f = File.open(\"hello.txt\").map_err(|error| {\n    if (error.kind()) == ErrorKind.NotFound {\n      File::create(\"hello.txt\").unwrap_or_else(|error| {\n        panic!(\"Tried to create file but there was a problem {:?}\", e)\n      })\n    } else {\n      panic!(\"There was a problem opening file: {:?}\", error)\n    }\n  })\n}\n```\n\n### Shortcuts for Panic on Error: unwrap and expect\n\n- Using `match` works well but verbose\n- `Result\u003cT, E\u003e` type has many helper methods defined\n- `Ok` variant in `Result` reutn the value inside the `Ok`\n- `Err` variant in `Result`, `unwrap` will call `panic!`\n\n```rust\nuse std::fs::File;\n\nfn main() {\n // panic! call without hello.txt\n  let greeting_file = File::open(\"hello.txt\").unwrap();\n}\n```\n\n- `expect` lets us choose the `panic!` error message\n- Using `expect` instead of `unwrap` and providing `good error message`\n\n```rust\nuse std:fs:File;\n\nfn main() {\n  // unwarp, shortcut method of match, return Ok or Err\n  let f = File::open(\"hello.txt\").unwrap()\n\n  // expect, let us choos the panic, return the fild handle or call panic! macro\n  let f = File::open(\"hello.txt\").expect(\"Failed to open hello.txt)\n}\n```\n\n### Propagating Errors\n\n- Return the error to the calling code instead of handling the error within the function itself\n\n```rust\nfn read_username_from_file() -\u003e Rsult\u003cString, io::Error\u003e {\n  let f = File::open(\"hello.txt\");\n\n  let mut f = match f {\n    Ok(file) =\u003e file,        // return String\n    Err(e) =\u003e return Err(e), // return error to the code that called the function\n                             // use the return keyword to return early out of the\n                             // function entirely and pass the error value from File::open\n  }\n\n  let mut s = String::new();\n\n  match f.read_to_string(\u0026mut s) {\n    Ok(_) =\u003e Ok(s),\n    Err(e) =\u003e Err(e), // return error\n  }\n}\n```\n\n#### A Shortcut for Propagating Errors: the ? Operator\n\n- Uses the ? operator, placed after a Result value is defined to work in almost the same way as the match expressions we defined to handle the Result values\n\n```rust\nuse std::fs::File;\nuse std::io::{self, Read};\n\nfn read_username_from_file() -\u003e Result\u003cString, io::Error\u003e {\n    let mut username_file = File::open(\"hello.txt\")?;\n    let mut username = String::new();\n    username_file.read_to_string(\u0026mut username)?;\n    Ok(username)\n}\n```\n\n- Shorten the code futher by chaining mehtod call immediately after the `?`\n\n```rust\nuse std::fs::File;\nuse std::io::{self, Read};\n\nfn read_username_from_file() -\u003e Result\u003cString, io::Error\u003e {\n  let mut s = String::new();\n  File::open(\"hello.txt\")?.read_to_string(\u0026mut s)?;\n  Ok(s)\n}\n```\n\n- More shorten the code by using `fs::read_to_string`\n\n```rust\nfn read_username_from_file() -\u003e Result\u003cString, io::Error\u003e {\n  fs::read_to_string(\"hello.txt\")\n}\n```\n\n#### Where The ? Operator Can Be Used\n\n- `?` operator can only be used in functions whose return type is compatible with the value the `?` is used on\n\n```rust\nfn main() { // main is incompatible with `Result` or `Option`\n  let f = File::open(\"hello.txt\"); // ^ cannot use the `?` operator in a function that returns `()`\n}\n```\n\n- `?` can be used with `Option\u003cT\u003e` values\n- The behavior of the ? operator when called on an Option\u003cT\u003e is similar to its behavior when called on a Result\u003cT, E\u003e\n- If the value is None, the None will be returned early from the function at that point\n- If the value is Some, the value inside the Some is the resulting value of the expression and the function continues\n\n```rust\nfn last_char_of_first_line(text: \u0026str) -\u003e Option\u003cchar\u003e {\n    text.lines().next()?.chars().last()\n}\n```\n\n- Because it’s the entry and exit point of executable programs, and `there are restrictions` on what its return type can be for the programs to behave as expected.\n  - Main can also return a Result\u003c(), E\u003e\n  - You can read Box\u003cdyn Error\u003e to mean “any kind of error.” \n- Main function returns a Result\u003c(), E\u003e, the executable will exit with a value of 0 if main returns Ok(())\n- Main function will exit with a nonzero value if main returns an Err value\n\n```rust\nuse std::error::Error;\nuse std::fs::File;\n\nfn main() -\u003e Result\u003c(), Box\u003cdyn Error\u003e\u003e {\n    let greeting_file = File::open(\"hello.txt\")?;\n\n    Ok(())\n}\n```\n\n## To panic! or Not ro panic!\n\n- You could call panic! for any error situation, whether there’s a possible way to recover or not, but then you’re making the decision that a situation is unrecoverable on behalf of the calling code. When you choose to return a Result value, you give the calling code options\n\n### Examples, Prototype Code, and Tests\n\nWhen you’re writing an example to illustrate some concept, also including robust error-handling code can make the example less clear. In examples, it’s understood that a call to a method like unwrap that could panic is meant as a placeholder for the way you’d want your application to handle errors, which can differ based on what the rest of your code is doing.\n\n### Cases in Which You Have More Information Than the Compiler\n\nif you can ensure by manually inspecting the code that you’ll never have an Err variant, it’s perfectly acceptable to call unwrap, and even better to document the reason you think you’ll never have an Err variant in the expect text.\n\n```rust\n  use std::net::IpAddr;\n\n  let home: IpAddr = \"127.0.0.1\"\n      .parse()\n      .expect(\"Hardcoded IP address should be valid\");\n```\n\n### Guidelines for Error Handling\n\n- Panic when it’s possible that your code could end up in a `bad state`\n- The `bad state` is something that is unexpected, as opposed to something that will likely happen occasionally, like a user entering data in the wrong forma\n- Your code after this point needs to rely on not being in this bad state, rather than checking for the problem at every step.\n- There’s not a good way to encode this information in the types you use\n\n\u003e If someone calls your code and passes in values that don’t make sense, it’s best to return an error if you can so the user of the library can decide what they want to do in that case. However, in cases where continuing could be insecure or harmful, the best choice might be to call panic! and alert the person using your library to the bug in their code so they can fix it during development. However, when failure is expected, it’s more appropriate to return a Result than to make a panic! call\n\n### Creating Custom Types for Validation\n\n- Parse the guess as an i32 instread of only a u32 to allow potentially negative numbers, and then add a check for the number being in range\n- However, this is not an ideal solution: if it was absolutely critical that the program only operated on values between 1 and 100, and it had many functions with this requirement, having a check like this in every function would be tedious\n\n```rust\nloop {\n    // --snip--\n\n    let guess: i32 = match guess.trim().parse() {\n        Ok(num) =\u003e num,\n        Err(_) =\u003e continue,\n    };\n\n    if guess \u003c 1 || guess \u003e 100 {\n        println!(\"The secret number will be between 1 and 100.\");\n        continue;\n    }\n\n    match guess.cmp(\u0026secret_number) {\n    // --snip--\n}\n\n- If value doesn’t pass this test, we make a panic! call, which will alert the programmer who is writing the calling code that they have a bug they need to fix, because creating a Guess with a value outside this range would violate the contract that Guess::new is relying on\n- Function that has a parameter or returns only numbers between 1 and 100 could then declare in its signature that it takes or returns a Guess rather than an i32 and wouldn’t need to do any additional checks in its body.\n\npub struct Guess {\n    value: i32,\n}\n\nimpl Guess {\n    pub fn new(value: i32) -\u003e Guess {\n        if value \u003c 1 || value \u003e 100 {\n            panic!(\"Guess value must be between 1 and 100, got {}.\", value);\n        }\n\n        Guess {\n            value\n        }\n    }\n\n    pub fn value(\u0026self) -\u003e i32 {\n        self.value\n    }\n}\n```\n\n# Generic Types, Traits, and Lifetimes\n\n- `generic` is tool for effectively handling the duplication of concepts in Rust\n- Functions can take parameter of some generic type\n- `traits` define behavior in a generic way which can combine with generic types to constrain a generic type to accept only those types that a particular behavior as opposed to just any type\n\n## Removing Duplication by Extracting a Function\n\n- We've now been tasked with finding the largest number in two different lists of numbers\n\n```rust\nfn main() {\n    let number_list = vec![34, 50, 25, 100, 65];\n\n    let mut largest = \u0026number_list[0];\n\n    for number in \u0026number_list {\n        if number \u003e largest {\n            largest = number;\n        }\n    }\n\n    println!(\"The largest number is {}\", largest);\n\n    let number_list = vec![102, 34, 6000, 89, 54, 2, 43, 8];\n\n    let mut largest = \u0026number_list[0];\n\n    for number in \u0026number_list {\n        if number \u003e largest {\n            largest = number;\n        }\n    }\n\n    println!(\"The largest number is {}\", largest);\n}\n```\n\n- Identify duplicate code.\n- Extract the duplicate code into the body of the function and specify the inputs and return values of that code in the function signature.\n- Update the two instances of duplicated code to call the function instead.\n\n```rust\nfn largest(list: \u0026[i32]) -\u003e \u0026i32 {\n    let mut largest = \u0026list[0];\n\n    for item in list {\n        if item \u003e largest {\n            largest = item;\n        }\n    }\n\n    largest\n}\n\nfn main() {\n    let number_list = vec![34, 50, 25, 100, 65];\n\n    let result = largest(\u0026number_list);\n    println!(\"The largest number is {}\", result);\n\n    let number_list = vec![102, 34, 6000, 89, 54, 2, 43, 8];\n\n    let result = largest(\u0026number_list);\n    println!(\"The largest number is {}\", result);\n}\n```\n\n## Generic Data Types\n\n### In Function Definitions\n\n- Place the generics in the signature of the function where we would usually specify the data types of th","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fragingwind%2Frust-programming-language-summary","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fragingwind%2Frust-programming-language-summary","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fragingwind%2Frust-programming-language-summary/lists"}