Full Code of sunface/rust-by-practice for AI

master 90799d8656ee cached
294 files
722.1 KB
219.4k tokens
195 symbols
1 requests
Download .txt
Showing preview only (790K chars total). Download the full file or copy to clipboard to get everything.
Repository: sunface/rust-by-practice
Branch: master
Commit: 90799d8656ee
Files: 294
Total size: 722.1 KB

Directory structure:
gitextract_vvz_1z8d/

├── .gitignore
├── .prettierignore
├── LICENSE
├── Readme.md
├── en/
│   ├── assets/
│   │   ├── CNAME
│   │   ├── custom3.js
│   │   ├── lang1.js
│   │   └── temp.md
│   ├── book.toml
│   ├── deploy.sh
│   ├── src/
│   │   ├── .gitignore
│   │   ├── SUMMARY.md
│   │   ├── about.md
│   │   ├── async/
│   │   │   ├── async-await.md
│   │   │   ├── future.md
│   │   │   ├── intro.md
│   │   │   ├── pin-unpin.md
│   │   │   └── stream.md
│   │   ├── basic-types/
│   │   │   ├── char-bool-unit.md
│   │   │   ├── functions.md
│   │   │   ├── intro.md
│   │   │   ├── numbers.md
│   │   │   └── statements-expressions.md
│   │   ├── circle-reference/
│   │   │   └── intro.md
│   │   ├── collections/
│   │   │   ├── hashmap.md
│   │   │   ├── intro.md
│   │   │   ├── string.md
│   │   │   └── vector.md
│   │   ├── comments-docs.md
│   │   ├── compound-types/
│   │   │   ├── array.md
│   │   │   ├── enum.md
│   │   │   ├── intro.md
│   │   │   ├── slice.md
│   │   │   ├── string.md
│   │   │   ├── struct.md
│   │   │   └── tuple.md
│   │   ├── crate-module/
│   │   │   ├── crate.md
│   │   │   ├── intro.md
│   │   │   ├── module.md
│   │   │   └── use-pub.md
│   │   ├── elegant-code-base.md
│   │   ├── errors.md
│   │   ├── fight-compiler/
│   │   │   ├── borrowing.md
│   │   │   └── intro.md
│   │   ├── flow-control.md
│   │   ├── formatted-output/
│   │   │   ├── debug-display.md
│   │   │   ├── formatting.md
│   │   │   ├── intro.md
│   │   │   └── println.md
│   │   ├── functional-programing/
│   │   │   ├── closure.md
│   │   │   ├── intro.md
│   │   │   └── iterator.md
│   │   ├── generics-traits/
│   │   │   ├── advanced-traits.md
│   │   │   ├── const-generics.md
│   │   │   ├── generics.md
│   │   │   ├── intro.md
│   │   │   ├── trait-object.md
│   │   │   └── traits.md
│   │   ├── global-variables.md
│   │   ├── lifetime/
│   │   │   ├── advance.md
│   │   │   ├── basic.md
│   │   │   ├── intro.md
│   │   │   └── static.md
│   │   ├── macro.md
│   │   ├── method.md
│   │   ├── newtype-sized.md
│   │   ├── ownership/
│   │   │   ├── borrowing.md
│   │   │   ├── intro.md
│   │   │   └── ownership.md
│   │   ├── pattern-match/
│   │   │   ├── intro.md
│   │   │   ├── match-iflet.md
│   │   │   └── patterns.md
│   │   ├── result-panic/
│   │   │   ├── intro.md
│   │   │   ├── panic.md
│   │   │   └── result.md
│   │   ├── self-referential.md
│   │   ├── smart-pointers/
│   │   │   ├── box.md
│   │   │   ├── cell-refcell.md
│   │   │   ├── deref.md
│   │   │   ├── drop.md
│   │   │   ├── intro.md
│   │   │   └── rc-arc.md
│   │   ├── std/
│   │   │   ├── String.md
│   │   │   └── intro.md
│   │   ├── tests/
│   │   │   ├── assertions.md
│   │   │   ├── benchmark.md
│   │   │   ├── intro.md
│   │   │   ├── unit-integration.md
│   │   │   └── write-tests.md
│   │   ├── threads/
│   │   │   ├── atomic.md
│   │   │   ├── basic-using.md
│   │   │   ├── intro.md
│   │   │   ├── message-passing.md
│   │   │   ├── send-sync.md
│   │   │   └── sync.md
│   │   ├── type-conversions/
│   │   │   ├── as.md
│   │   │   ├── from-into.md
│   │   │   ├── intro.md
│   │   │   └── others.md
│   │   ├── unsafe/
│   │   │   ├── inline-asm.md
│   │   │   └── intro.md
│   │   ├── variables.md
│   │   ├── weak.md
│   │   └── why-exercise.md
│   └── theme/
│       ├── index1.hbs
│       └── style1.css
├── practices/
│   ├── doc-comments/
│   │   ├── .gitignore
│   │   ├── Cargo.toml
│   │   ├── Readme.md
│   │   └── src/
│   │       ├── compute.rs
│   │       └── lib.rs
│   └── hello-package/
│       ├── .gitignore
│       ├── Cargo.toml
│       ├── Readme.md
│       └── src/
│           ├── back_of_house.rs
│           ├── front_of_house/
│           │   ├── hosting.rs
│           │   ├── mod.rs
│           │   └── serving.rs
│           ├── lib.rs
│           └── main.rs
├── scripts/
│   └── link_solution
├── solutions/
│   ├── basic-types/
│   │   ├── char-bool.md
│   │   ├── functions.md
│   │   ├── numbers.md
│   │   └── statements.md
│   ├── collections/
│   │   ├── Hashmap.md
│   │   ├── String.md
│   │   └── Vector.md
│   ├── compound-types/
│   │   ├── array.md
│   │   ├── enum.md
│   │   ├── slice.md
│   │   ├── string.md
│   │   ├── struct.md
│   │   └── tuple.md
│   ├── crate-module/
│   │   ├── crate.md
│   │   ├── module.md
│   │   └── use-pub.md
│   ├── fight-compiler/
│   │   └── borrowing.md
│   ├── flow-control.md
│   ├── formatted-output/
│   │   ├── debug-display.md
│   │   ├── formatting.md
│   │   └── println.md
│   ├── functional-programing/
│   │   ├── closure.md
│   │   └── iterator.md
│   ├── generics-traits/
│   │   ├── advanced-trait.md
│   │   ├── const-generics.md
│   │   ├── generics.md
│   │   ├── trait-object.md
│   │   └── traits.md
│   ├── lifetime/
│   │   ├── advance.md
│   │   ├── basic.md
│   │   └── static.md
│   ├── method.md
│   ├── newtype-sized.md
│   ├── ownership/
│   │   ├── borrowing.md
│   │   └── ownership.md
│   ├── pattern-match/
│   │   ├── match.md
│   │   └── patterns.md
│   ├── result-panic/
│   │   ├── panic.md
│   │   └── result.md
│   ├── type-conversions/
│   │   ├── as.md
│   │   ├── from-into.md
│   │   └── others.md
│   └── variables.md
└── zh-CN/
    ├── assets/
    │   ├── CNAME
    │   ├── custom3.js
    │   ├── lang1.js
    │   └── mini-redis/
    │       ├── .github/
    │       │   └── workflows/
    │       │       └── ci.yml
    │       ├── .gitignore
    │       ├── Cargo.toml
    │       ├── LICENSE
    │       ├── README.md
    │       ├── examples/
    │       │   ├── chat.rs
    │       │   ├── hello_world.rs
    │       │   ├── pub.rs
    │       │   └── sub.rs
    │       ├── src/
    │       │   ├── bin/
    │       │   │   ├── cli.rs
    │       │   │   └── server.rs
    │       │   ├── blocking_client.rs
    │       │   ├── buffer.rs
    │       │   ├── client.rs
    │       │   ├── cmd/
    │       │   │   ├── get.rs
    │       │   │   ├── mod.rs
    │       │   │   ├── publish.rs
    │       │   │   ├── set.rs
    │       │   │   ├── subscribe.rs
    │       │   │   └── unknown.rs
    │       │   ├── connection.rs
    │       │   ├── db.rs
    │       │   ├── frame.rs
    │       │   ├── lib.rs
    │       │   ├── parse.rs
    │       │   ├── server.rs
    │       │   └── shutdown.rs
    │       └── tests/
    │           ├── buffer.rs
    │           ├── client.rs
    │           └── server.rs
    ├── book.toml
    ├── deploy.sh
    ├── src/
    │   ├── SUMMARY.md
    │   ├── about.md
    │   ├── async/
    │   │   ├── async-await.md
    │   │   ├── future.md
    │   │   ├── intro.md
    │   │   ├── pin-unpin.md
    │   │   └── stream.md
    │   ├── basic-types/
    │   │   ├── char-bool-unit.md
    │   │   ├── functions.md
    │   │   ├── intro.md
    │   │   ├── numbers.md
    │   │   └── statements-expressions.md
    │   ├── circle-reference/
    │   │   └── intro.md
    │   ├── collections/
    │   │   ├── hashmap.md
    │   │   ├── intro.md
    │   │   ├── string.md
    │   │   └── vector.md
    │   ├── comments-docs.md
    │   ├── compound-types/
    │   │   ├── array.md
    │   │   ├── enum.md
    │   │   ├── intro.md
    │   │   ├── slice.md
    │   │   ├── string.md
    │   │   ├── struct.md
    │   │   └── tuple.md
    │   ├── crate-module/
    │   │   ├── crate.md
    │   │   ├── intro.md
    │   │   ├── module.md
    │   │   └── use-pub.md
    │   ├── elegant-code-base.md
    │   ├── errors.md
    │   ├── fight-compiler/
    │   │   ├── borrowing.md
    │   │   └── intro.md
    │   ├── flow-control.md
    │   ├── formatted-output/
    │   │   ├── debug-display.md
    │   │   ├── formatting.md
    │   │   ├── intro.md
    │   │   └── println.md
    │   ├── functional-programing/
    │   │   ├── closure.md
    │   │   ├── intro.md
    │   │   └── iterator.md
    │   ├── generics-traits/
    │   │   ├── advanced-traits.md
    │   │   ├── const-generics.md
    │   │   ├── generics.md
    │   │   ├── intro.md
    │   │   ├── trait-object.md
    │   │   └── traits.md
    │   ├── global-variables.md
    │   ├── lifetime/
    │   │   ├── advance.md
    │   │   ├── basic.md
    │   │   ├── intro.md
    │   │   └── static.md
    │   ├── macro.md
    │   ├── method.md
    │   ├── newtype-sized.md
    │   ├── ownership/
    │   │   ├── borrowing.md
    │   │   ├── intro.md
    │   │   └── ownership.md
    │   ├── pattern-match/
    │   │   ├── intro.md
    │   │   ├── match-iflet.md
    │   │   └── patterns.md
    │   ├── result-panic/
    │   │   ├── intro.md
    │   │   ├── panic.md
    │   │   └── result.md
    │   ├── self-referential.md
    │   ├── smart-pointers/
    │   │   ├── box.md
    │   │   ├── cell-refcell.md
    │   │   ├── deref.md
    │   │   ├── drop.md
    │   │   ├── intro.md
    │   │   └── rc-arc.md
    │   ├── std/
    │   │   ├── String.md
    │   │   └── intro.md
    │   ├── tests/
    │   │   ├── assertions.md
    │   │   ├── benchmark.md
    │   │   ├── intro.md
    │   │   ├── unit-integration.md
    │   │   └── write-tests.md
    │   ├── threads/
    │   │   ├── atomic.md
    │   │   ├── basic-using.md
    │   │   ├── intro.md
    │   │   ├── message-passing.md
    │   │   ├── send-sync.md
    │   │   └── sync.md
    │   ├── type-conversions/
    │   │   ├── as.md
    │   │   ├── from-into.md
    │   │   ├── intro.md
    │   │   └── others.md
    │   ├── unsafe/
    │   │   ├── inline-asm.md
    │   │   └── intro.md
    │   ├── variables.md
    │   ├── weak.md
    │   └── why-exercise.md
    └── theme/
        ├── index1.hbs
        └── style1.css

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
en/book
zh-CN/book
**/.DS_Store


================================================
FILE: .prettierignore
================================================
*.md

================================================
FILE: LICENSE
================================================
Attribution 4.0 International

=======================================================================

Creative Commons Corporation ("Creative Commons") is not a law firm and
does not provide legal services or legal advice. Distribution of
Creative Commons public licenses does not create a lawyer-client or
other relationship. Creative Commons makes its licenses and related
information available on an "as-is" basis. Creative Commons gives no
warranties regarding its licenses, any material licensed under their
terms and conditions, or any related information. Creative Commons
disclaims all liability for damages resulting from their use to the
fullest extent possible.

Using Creative Commons Public Licenses

Creative Commons public licenses provide a standard set of terms and
conditions that creators and other rights holders may use to share
original works of authorship and other material subject to copyright
and certain other rights specified in the public license below. The
following considerations are for informational purposes only, are not
exhaustive, and do not form part of our licenses.

     Considerations for licensors: Our public licenses are
     intended for use by those authorized to give the public
     permission to use material in ways otherwise restricted by
     copyright and certain other rights. Our licenses are
     irrevocable. Licensors should read and understand the terms
     and conditions of the license they choose before applying it.
     Licensors should also secure all rights necessary before
     applying our licenses so that the public can reuse the
     material as expected. Licensors should clearly mark any
     material not subject to the license. This includes other CC-
     licensed material, or material used under an exception or
     limitation to copyright. More considerations for licensors:
	wiki.creativecommons.org/Considerations_for_licensors

     Considerations for the public: By using one of our public
     licenses, a licensor grants the public permission to use the
     licensed material under specified terms and conditions. If
     the licensor's permission is not necessary for any reason--for
     example, because of any applicable exception or limitation to
     copyright--then that use is not regulated by the license. Our
     licenses grant only permissions under copyright and certain
     other rights that a licensor has authority to grant. Use of
     the licensed material may still be restricted for other
     reasons, including because others have copyright or other
     rights in the material. A licensor may make special requests,
     such as asking that all changes be marked or described.
     Although not required by our licenses, you are encouraged to
     respect those requests where reasonable. More_considerations
     for the public:
	wiki.creativecommons.org/Considerations_for_licensees

=======================================================================

Creative Commons Attribution 4.0 International Public License

By exercising the Licensed Rights (defined below), You accept and agree
to be bound by the terms and conditions of this Creative Commons
Attribution 4.0 International Public License ("Public License"). To the
extent this Public License may be interpreted as a contract, You are
granted the Licensed Rights in consideration of Your acceptance of
these terms and conditions, and the Licensor grants You such rights in
consideration of benefits the Licensor receives from making the
Licensed Material available under these terms and conditions.


Section 1 -- Definitions.

  a. Adapted Material means material subject to Copyright and Similar
     Rights that is derived from or based upon the Licensed Material
     and in which the Licensed Material is translated, altered,
     arranged, transformed, or otherwise modified in a manner requiring
     permission under the Copyright and Similar Rights held by the
     Licensor. For purposes of this Public License, where the Licensed
     Material is a musical work, performance, or sound recording,
     Adapted Material is always produced where the Licensed Material is
     synched in timed relation with a moving image.

  b. Adapter's License means the license You apply to Your Copyright
     and Similar Rights in Your contributions to Adapted Material in
     accordance with the terms and conditions of this Public License.

  c. Copyright and Similar Rights means copyright and/or similar rights
     closely related to copyright including, without limitation,
     performance, broadcast, sound recording, and Sui Generis Database
     Rights, without regard to how the rights are labeled or
     categorized. For purposes of this Public License, the rights
     specified in Section 2(b)(1)-(2) are not Copyright and Similar
     Rights.

  d. Effective Technological Measures means those measures that, in the
     absence of proper authority, may not be circumvented under laws
     fulfilling obligations under Article 11 of the WIPO Copyright
     Treaty adopted on December 20, 1996, and/or similar international
     agreements.

  e. Exceptions and Limitations means fair use, fair dealing, and/or
     any other exception or limitation to Copyright and Similar Rights
     that applies to Your use of the Licensed Material.

  f. Licensed Material means the artistic or literary work, database,
     or other material to which the Licensor applied this Public
     License.

  g. Licensed Rights means the rights granted to You subject to the
     terms and conditions of this Public License, which are limited to
     all Copyright and Similar Rights that apply to Your use of the
     Licensed Material and that the Licensor has authority to license.

  h. Licensor means the individual(s) or entity(ies) granting rights
     under this Public License.

  i. Share means to provide material to the public by any means or
     process that requires permission under the Licensed Rights, such
     as reproduction, public display, public performance, distribution,
     dissemination, communication, or importation, and to make material
     available to the public including in ways that members of the
     public may access the material from a place and at a time
     individually chosen by them.

  j. Sui Generis Database Rights means rights other than copyright
     resulting from Directive 96/9/EC of the European Parliament and of
     the Council of 11 March 1996 on the legal protection of databases,
     as amended and/or succeeded, as well as other essentially
     equivalent rights anywhere in the world.

  k. You means the individual or entity exercising the Licensed Rights
     under this Public License. Your has a corresponding meaning.


Section 2 -- Scope.

  a. License grant.

       1. Subject to the terms and conditions of this Public License,
          the Licensor hereby grants You a worldwide, royalty-free,
          non-sublicensable, non-exclusive, irrevocable license to
          exercise the Licensed Rights in the Licensed Material to:

            a. reproduce and Share the Licensed Material, in whole or
               in part; and

            b. produce, reproduce, and Share Adapted Material.

       2. Exceptions and Limitations. For the avoidance of doubt, where
          Exceptions and Limitations apply to Your use, this Public
          License does not apply, and You do not need to comply with
          its terms and conditions.

       3. Term. The term of this Public License is specified in Section
          6(a).

       4. Media and formats; technical modifications allowed. The
          Licensor authorizes You to exercise the Licensed Rights in
          all media and formats whether now known or hereafter created,
          and to make technical modifications necessary to do so. The
          Licensor waives and/or agrees not to assert any right or
          authority to forbid You from making technical modifications
          necessary to exercise the Licensed Rights, including
          technical modifications necessary to circumvent Effective
          Technological Measures. For purposes of this Public License,
          simply making modifications authorized by this Section 2(a)
          (4) never produces Adapted Material.

       5. Downstream recipients.

            a. Offer from the Licensor -- Licensed Material. Every
               recipient of the Licensed Material automatically
               receives an offer from the Licensor to exercise the
               Licensed Rights under the terms and conditions of this
               Public License.

            b. No downstream restrictions. You may not offer or impose
               any additional or different terms or conditions on, or
               apply any Effective Technological Measures to, the
               Licensed Material if doing so restricts exercise of the
               Licensed Rights by any recipient of the Licensed
               Material.

       6. No endorsement. Nothing in this Public License constitutes or
          may be construed as permission to assert or imply that You
          are, or that Your use of the Licensed Material is, connected
          with, or sponsored, endorsed, or granted official status by,
          the Licensor or others designated to receive attribution as
          provided in Section 3(a)(1)(A)(i).

  b. Other rights.

       1. Moral rights, such as the right of integrity, are not
          licensed under this Public License, nor are publicity,
          privacy, and/or other similar personality rights; however, to
          the extent possible, the Licensor waives and/or agrees not to
          assert any such rights held by the Licensor to the limited
          extent necessary to allow You to exercise the Licensed
          Rights, but not otherwise.

       2. Patent and trademark rights are not licensed under this
          Public License.

       3. To the extent possible, the Licensor waives any right to
          collect royalties from You for the exercise of the Licensed
          Rights, whether directly or through a collecting society
          under any voluntary or waivable statutory or compulsory
          licensing scheme. In all other cases the Licensor expressly
          reserves any right to collect such royalties.


Section 3 -- License Conditions.

Your exercise of the Licensed Rights is expressly made subject to the
following conditions.

  a. Attribution.

       1. If You Share the Licensed Material (including in modified
          form), You must:

            a. retain the following if it is supplied by the Licensor
               with the Licensed Material:

                 i. identification of the creator(s) of the Licensed
                    Material and any others designated to receive
                    attribution, in any reasonable manner requested by
                    the Licensor (including by pseudonym if
                    designated);

                ii. a copyright notice;

               iii. a notice that refers to this Public License;

                iv. a notice that refers to the disclaimer of
                    warranties;

                 v. a URI or hyperlink to the Licensed Material to the
                    extent reasonably practicable;

            b. indicate if You modified the Licensed Material and
               retain an indication of any previous modifications; and

            c. indicate the Licensed Material is licensed under this
               Public License, and include the text of, or the URI or
               hyperlink to, this Public License.

       2. You may satisfy the conditions in Section 3(a)(1) in any
          reasonable manner based on the medium, means, and context in
          which You Share the Licensed Material. For example, it may be
          reasonable to satisfy the conditions by providing a URI or
          hyperlink to a resource that includes the required
          information.

       3. If requested by the Licensor, You must remove any of the
          information required by Section 3(a)(1)(A) to the extent
          reasonably practicable.

       4. If You Share Adapted Material You produce, the Adapter's
          License You apply must not prevent recipients of the Adapted
          Material from complying with this Public License.


Section 4 -- Sui Generis Database Rights.

Where the Licensed Rights include Sui Generis Database Rights that
apply to Your use of the Licensed Material:

  a. for the avoidance of doubt, Section 2(a)(1) grants You the right
     to extract, reuse, reproduce, and Share all or a substantial
     portion of the contents of the database;

  b. if You include all or a substantial portion of the database
     contents in a database in which You have Sui Generis Database
     Rights, then the database in which You have Sui Generis Database
     Rights (but not its individual contents) is Adapted Material; and

  c. You must comply with the conditions in Section 3(a) if You Share
     all or a substantial portion of the contents of the database.

For the avoidance of doubt, this Section 4 supplements and does not
replace Your obligations under this Public License where the Licensed
Rights include other Copyright and Similar Rights.


Section 5 -- Disclaimer of Warranties and Limitation of Liability.

  a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
     EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
     AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
     ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
     IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
     WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
     PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
     ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
     KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
     ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.

  b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
     TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
     NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
     INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
     COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
     USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
     ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
     DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
     IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.

  c. The disclaimer of warranties and limitation of liability provided
     above shall be interpreted in a manner that, to the extent
     possible, most closely approximates an absolute disclaimer and
     waiver of all liability.


Section 6 -- Term and Termination.

  a. This Public License applies for the term of the Copyright and
     Similar Rights licensed here. However, if You fail to comply with
     this Public License, then Your rights under this Public License
     terminate automatically.

  b. Where Your right to use the Licensed Material has terminated under
     Section 6(a), it reinstates:

       1. automatically as of the date the violation is cured, provided
          it is cured within 30 days of Your discovery of the
          violation; or

       2. upon express reinstatement by the Licensor.

     For the avoidance of doubt, this Section 6(b) does not affect any
     right the Licensor may have to seek remedies for Your violations
     of this Public License.

  c. For the avoidance of doubt, the Licensor may also offer the
     Licensed Material under separate terms or conditions or stop
     distributing the Licensed Material at any time; however, doing so
     will not terminate this Public License.

  d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
     License.


Section 7 -- Other Terms and Conditions.

  a. The Licensor shall not be bound by any additional or different
     terms or conditions communicated by You unless expressly agreed.

  b. Any arrangements, understandings, or agreements regarding the
     Licensed Material not stated herein are separate from and
     independent of the terms and conditions of this Public License.


Section 8 -- Interpretation.

  a. For the avoidance of doubt, this Public License does not, and
     shall not be interpreted to, reduce, limit, restrict, or impose
     conditions on any use of the Licensed Material that could lawfully
     be made without permission under this Public License.

  b. To the extent possible, if any provision of this Public License is
     deemed unenforceable, it shall be automatically reformed to the
     minimum extent necessary to make it enforceable. If the provision
     cannot be reformed, it shall be severed from this Public License
     without affecting the enforceability of the remaining terms and
     conditions.

  c. No term or condition of this Public License will be waived and no
     failure to comply consented to unless expressly agreed to by the
     Licensor.

  d. Nothing in this Public License constitutes or may be interpreted
     as a limitation upon, or waiver of, any privileges and immunities
     that apply to the Licensor or You, including from the legal
     processes of any jurisdiction or authority.


=======================================================================

Creative Commons is not a party to its public
licenses. Notwithstanding, Creative Commons may elect to apply one of
its public licenses to material it publishes and in those instances
will be considered the "Licensor." The text of the Creative Commons
public licenses is dedicated to the public domain under the CC0 Public
Domain Dedication. Except for the limited purpose of indicating that
material is shared under a Creative Commons public license or as
otherwise permitted by the Creative Commons policies published at
creativecommons.org/policies, Creative Commons does not authorize the
use of the trademark "Creative Commons" or any other trademark or logo
of Creative Commons without its prior written consent including,
without limitation, in connection with any unauthorized modifications
to any of its public licenses or any other arrangements,
understandings, or agreements concerning use of licensed material. For
the avoidance of doubt, this paragraph does not form part of the
public licenses.

Creative Commons may be contacted at creativecommons.org.


================================================
FILE: Readme.md
================================================
<div align="center">
    <img src="https://github.com/sunface/rust-by-practice/blob/master/en/assets/header.jpg?raw=true">
</div>

<p align="center">
    <span>English</span>
    <span> | </span>
    <a href="https://github.com/sunface/rust-by-practice/blob/master/zh-CN/src/why-exercise.md">中文</a>
</p>
    
<p align="center">Practice Rust with challenging examples, exercises and projects</p>
    
<div align="center">

[![Stars Count](https://img.shields.io/github/stars/sunface/rust-by-practice?style=flat)](https://github.com/sunface/rust-by-practice/stargazers) 
[![studyrut](https://img.shields.io/badge/RustCn-orange)](https://hirust.cn) 
[![LICENSE](https://img.shields.io/badge/license-CC_BY_4.0-green?style=flat)](https://github.com/sunface/rust-by-practice/blob/master/LICENSE)
</div>

This book was designed for easily diving into and getting skilled with Rust It's very easy to use. All you need to do is to make each exercise compile without ERRORS and Panics!


## Reading online

- [https://practice.rs](https://practice.rs)

## Features

Part of our examples and exercises are borrowed from [Rust By Example](https://github.com/rust-lang/rust-by-example), thanks for your great works!

Although they are so awesome, we have our own secret weapons :)

- There are three parts in each chapter: examples, exercises and practices

- Besides examples, we have `a lot of exercises`, you can Read, Edit and Run them ONLINE

- Covering nearly all aspects of Rust, such as async/await, threads, sync primitives, optimizing, standard libraries, tool chain, data structures and algorithms etc.

- Every exercise has its own solutions

- The overall difficulties are a bit higher and from easy to super hard: easy 🌟 medium 🌟🌟 hard 🌟🌟🌟 super hard 🌟🌟🌟🌟

**What we want to do is fill in the gap between learning and getting started with real projects.**

## 🏅 Contributors

Thanks to all of our [contributors](https://github.com/sunface/rust-by-practice/graphs/contributors)!

<br />

**🏆 Special thanks to our English editor:**
<table>
    <tr>
        <td align="center">
            <a href="https://github.com/Tanish-Eagle">
                <img src="https://avatars.githubusercontent.com/u/71984506?v=4?s=100" width="160px"   alt=""/>
                <br />
                <sub><b>Tanish-Eagle</b></sub>
            </a>
        </td>
    </tr>
</table>

<br />

## Running locally

We use [mdbook](https://rust-lang.github.io/mdBook/) building our exercises. You can run locally with below steps:

- Clone the repo
```shell
$ git clone https://github.com/sunface/rust-by-practice
```
- Install mdbook using Cargo
```shell
$ cargo install mdbook
```

- For Book in English
```shell
$ cd rust-by-practice && mdbook serve en/
```

- For Book in Chinese
```shell
$ cd rust-by-practice && mdbook serve zh-CN/
```

## Some of our exercises

🌟🌟🌟 Tuple struct looks similar to tuples, it has added meaning the struct name provides but has no named fields. It's useful when you want give the whole tuple a name, but don't care the fields's names.

```rust

// fix the error and fill the blanks
struct Color(i32, i32, i32);
struct Point(i32, i32, i32);
fn main() {
    let v = Point(___, ___, ___);
    check_color(v);
}

fn check_color(p: Color) {
    let (x, _, _) = p;
    assert_eq!(x, 0);
    assert_eq!(p.1, 127);
    assert_eq!(___, 255);
 }
```

🌟🌟 Within the destructuring of a single variable, both by-move and by-reference pattern bindings can be used at the same time. Doing this will result in a partial move of the variable, which means that parts of the variable will be moved while other parts stay. In such a case, the parent variable cannot be used afterwards as a whole, however the parts that are only referenced (and not moved) can still be used.
```rust

// fix errors to make it work
#[derive(Debug)]
struct File {
    name: String,
    data: String,
}
fn main() {
    let f = File {
        name: String::from("readme.md"),
        data: "Rust By Practice".to_string()
    };

    let _name = f.name;

    // ONLY modify this line
    println!("{}, {}, {:?}",f.name, f.data, f);
}
```

🌟🌟 A match guard is an additional if condition specified after the pattern in a match arm that must also match, along with the pattern matching, for that arm to be chosen.
```rust,editable

// fill in the blank to make the code work, `split` MUST be used
fn main() {
    let num = Some(4);
    let split = 5;
    match num {
        Some(x) __ => assert!(x < split),
        Some(x) => assert!(x >= split),
        None => (),
    }
}
```


================================================
FILE: en/assets/CNAME
================================================
practice.course.rs

================================================
FILE: en/assets/custom3.js
================================================
var initAll = function () {
    var path = window.location.pathname;
    if (path.endsWith("/print.html")) {
        return;
    }

    var images = document.querySelectorAll("main img")
    Array.prototype.forEach.call(images, function (img) {
        img.addEventListener("click", function () {
            BigPicture({
                el: img,
            });
        });
    });

    // Un-active everything when you click it
    Array.prototype.forEach.call(document.getElementsByClassName("pagetoc")[0].children, function (el) {
        el.addEventHandler("click", function () {
            Array.prototype.forEach.call(document.getElementsByClassName("pagetoc")[0].children, function (el) {
                el.classList.remove("active");
            });
            el.classList.add("active");
        });
    });

    var updateFunction = function () {
        var id = null;
        var elements = document.getElementsByClassName("header");
        Array.prototype.forEach.call(elements, function (el) {
            if (window.pageYOffset >= el.offsetTop) {
                id = el;
            }
        });

        Array.prototype.forEach.call(document.getElementsByClassName("pagetoc")[0].children, function (el) {
            el.classList.remove("active");
        });

        Array.prototype.forEach.call(document.getElementsByClassName("pagetoc")[0].children, function (el) {
            if (id == null) {
                return;
            }
            if (id.href.localeCompare(el.href) == 0) {
                el.classList.add("active");
            }
        });
    };

    var pagetoc = document.getElementsByClassName("pagetoc")[0];
    var elements = document.getElementsByClassName("header");
    Array.prototype.forEach.call(elements, function (el) {
        var link = document.createElement("a");

        // Indent shows hierarchy
        var indent = "";
        switch (el.parentElement.tagName) {
            case "H1":
                return;
            case "H3":
                indent = "20px";
                break;
            case "H4":
                indent = "40px";
                break;
            default:
                break;
        }

        link.appendChild(document.createTextNode(el.text));
        link.style.paddingLeft = indent;
        link.href = el.href;
        pagetoc.appendChild(link);
    });
    updateFunction.call();

    // Handle active elements on scroll
    window.addEventListener("scroll", updateFunction);

    document.getElementById("theme-list").addEventListener("click", function (e) {
        var iframe = document.querySelector('.giscus-frame');
        if (!iframe) return;
        var theme;
        if (e.target.className === "theme") {
            theme = e.target.id;
        } else {
            return;
        }

        // 若当前 mdbook 主题不是 Light 或 Rust ,则将 giscuz 主题设置为 transparent_dark
        var giscusTheme = "light"
        if (theme != "light" && theme != "rust") {
            giscusTheme = "transparent_dark";
        }

        var msg = {
            setConfig: {
                theme: giscusTheme
            }
        };
        iframe.contentWindow.postMessage({ giscus: msg }, 'https://giscus.app');
    });
    
    pagePath = pagePath.replace("index.md", "");
    pagePath = pagePath.replace(".md", "");
    if (pagePath.length > 0) {
        if (pagePath.charAt(pagePath.length-1) == "/"){
            pagePath = pagePath.substring(0, pagePath.length-1)
        }
    }else {
        pagePath = "index"
    }

    // add visitors count
    var ele = document.createElement("div");
    ele.setAttribute("align","center");
    var count = document.createElement("img")
    // count.setAttribute("src", "https://visitor-badge.glitch.me/badge?page_id=practice/en/" + path);
    count.setAttribute("src", "https://api.visitorbadge.io/api/visitors?labelColor=%23595959&countColor=%230d81c3&style=flat-square&path=practice/en/" + path);
    ele.appendChild(count);
    var divider =document.createElement("hr")

    document.getElementById("giscus-container").appendChild(ele);
    document.getElementById("giscus-container").appendChild(divider);
    
    // 选取浏览器默认使用的语言
    const lang = navigator.language || navigator.userLanguage

    // 若当前 mdbook 主题为 Light 或 Rust ,则将 giscuz 主题设置为 light
    var theme = "transparent_dark";
    const themeClass = document.getElementsByTagName("html")[0].className;
    if (themeClass.indexOf("light") != -1 || themeClass.indexOf("rust") != -1) {
        theme = "light"
    }

    var script = document.createElement("script")
    script.type = "text/javascript";
    script.src = "https://giscus.app/client.js";
    script.async = true;
    script.crossOrigin = "anonymous";
    script.setAttribute("data-repo", "sunface/rust-by-practice");
    script.setAttribute("data-repo-id", "MDEwOlJlcG9zaXRvcnkxMjk5OTAzOTY=");
    script.setAttribute("data-category", "Book Comments");
    script.setAttribute("data-category-id", "DIC_kwDOB79-_M4COQmx");
    script.setAttribute("data-mapping", "specific");
    script.setAttribute("data-term", pagePath);
    script.setAttribute("data-reactions-enabled", "1");
    script.setAttribute("data-emit-metadata", "0");
    script.setAttribute("data-input-position", "top");
    script.setAttribute("data-theme", theme);
    script.setAttribute("data-lang", lang == 'en-US' ? 'en' : lang);
    // 预先加载评论会更好,这样用户读到那边时,评论就加载好了
    // script.setAttribute("data-loading", "lazy");
    document.getElementById("giscus-container").appendChild(script);
};

window.addEventListener('load', initAll);

================================================
FILE: en/assets/lang1.js
================================================
(function () {
  var path = window.location.pathname;
  var link = "https://practice.course.rs" + path;
  var word = "English";
  var lang = "zh-CN";
  var changeLang = "切换到英语";

  if (window.location.href.indexOf("zh.") == -1) {
    link = "https://practice-zh.course.rs" + path;
    word = "简体中文";
    lang = "en";
    changeLang = "Switch to Chinese";
  }

  var lang_node = "";
  if (link != "") {
    lang_node =
      '<a href="' +
      link +
      '" title="' +
      changeLang +
      '" aria-label="' +
      changeLang +
      '"><i id="change-language-button" class="fa fa-language"> ' +
      word +
      "</i></a>";
  }

  console.log(lang_node);
  var insertNode = document.getElementsByClassName("right-buttons");
  if (insertNode.length > 0) {
    var html = insertNode[0].innerHTML;
    insertNode[0].innerHTML = html + lang_node;
  }
})();


================================================
FILE: en/assets/temp.md
================================================
# 字符、布尔、单元类型

### 字符
🌟
```rust

use std::mem::size_of_val;
fn main() {
    let c1 = 'a';
    assert_eq!(size_of_val(&c1),1); 

    let c2 = '中';
    assert_eq!(size_of_val(&c2),3); 
} 
```

🌟
```rust

fn main() {
    let c1 = "中";
    print_char(c1);
} 

fn print_char(c : char) {
    println!("{}", c);
}
```

### 布尔
🌟
```rust

// 让  println! 工作
fn main() {
    let _f: bool = false;

    let t = true;
    if !t {
        println!("hello, world");
    }
} 
```

🌟
```rust

fn main() {
    let f = true;
    let t = true && false;
    assert_eq!(t, f);
}
```


### 单元类型
🌟🌟
```rust

// 让代码工作,但不要修改 `implicitly_ret_unit` !
fn main() {
    let _v: () = ();

    let v = (2, 3);
    assert_eq!(v, implicitly_ret_unit())
}

fn implicitly_ret_unit() {
    println!("I will returen a ()")
}

// 不要使用下面的函数,它只用于演示!
fn explicitly_ret_unit() -> () {
    println!("I will returen a ()")
}
```

🌟🌟 单元类型占用的内存大小是多少?
```rust

// 让代码工作:修改 `assert!` 中的 `4` 
use std::mem::size_of_val;
fn main() {
    let unit: () = ();
    assert!(size_of_val(&unit) == 4);
}
```

================================================
FILE: en/book.toml
================================================
[book]
title = "Rust By Practice"
description = "Learn Rust with Example, Exercise and real Practice, written with ❤️ by https://course.rs team"
authors = ["sunface, https://im.dev"]
language = "en"

[output.html.playpen]
editable = true
editor = "ace"

[output.html.fold]
enable = true
level = 1

[output.html]
additional-css = ["theme/style1.css"]
additional-js = ["assets/custom3.js", "assets/lang1.js"]
git-repository-url = "https://github.com/sunface/rust-by-practice"
edit-url-template = "https://github.com/sunface/rust-by-practice/edit/master/en/{path}"

[rust]
edition = "2021"


================================================
FILE: en/deploy.sh
================================================
## this script deploys the static website of course.rs to github pages

## build static website for book
mdbook build
## copy CNAME info to book dir
cp ./assets/CNAME ./book/

## init git repo
cd book
git init
git config user.name "sunface"
git config user.email "cto@188.com"
git add .
git commit -m 'deploy'
git branch -M gh-pages
git remote add origin https://github.com/sunface/rust-by-practice

## push to github pages
git push -u -f origin gh-pages

================================================
FILE: en/src/.gitignore
================================================
book

================================================
FILE: en/src/SUMMARY.md
================================================
# Summary

- [Rust By Practice](why-exercise.md)
- [Small projects with Elegant code](elegant-code-base.md)
- [Variables](variables.md)
- [Basic Types](basic-types/intro.md)
  - [Numbers](basic-types/numbers.md)
  - [Char, Bool and Unit](basic-types/char-bool-unit.md)
  - [Statements and Expressions](basic-types/statements-expressions.md)
  - [Functions](basic-types/functions.md)
- [Ownership and Borrowing](ownership/intro.md)
  - [Ownership](ownership/ownership.md)
  - [Reference and Borrowing](ownership/borrowing.md)
- [Compound Types](compound-types/intro.md)
  - [string](compound-types/string.md)
  - [Array](compound-types/array.md)
  - [Slice](compound-types/slice.md)
  - [Tuple](compound-types/tuple.md)
  - [Struct](compound-types/struct.md)
  - [Enum](compound-types/enum.md)
- [Flow Control](flow-control.md)
- [Pattern Match](pattern-match/intro.md)
  - [match, matches! and if let](pattern-match/match-iflet.md)
  - [Patterns](pattern-match/patterns.md)
- [Method & Associated function](method.md)
- [Generics and Traits](generics-traits/intro.md)
  - [Generics](generics-traits/generics.md)
  - [Const Generics](generics-traits/const-generics.md)
  - [Traits](generics-traits/traits.md)
  - [Trait Object](generics-traits/trait-object.md)
  - [Advanced Traits](generics-traits/advanced-traits.md)
- [Collection Types](collections/intro.md)
  - [String](collections/string.md)
  - [Vector](collections/vector.md)
  - [HashMap](collections/hashmap.md)
- [Type Conversion](type-conversions/intro.md)
  - [as](type-conversions/as.md)
  - [From/Into](type-conversions/from-into.md)
  - [Others](type-conversions/others.md)
- [Result and panic](result-panic/intro.md)
  - [panic!](result-panic/panic.md)
  - [Result and ?](result-panic/result.md)
- [Crate and Module](crate-module/intro.md)
  - [Package and Crate](crate-module/crate.md)
  - [Module](crate-module/module.md)
  - [Advanced use and pub](crate-module/use-pub.md)
- [Comments and Docs](comments-docs.md)
- [Formatted output](formatted-output/intro.md)
  - [println! and format!](formatted-output/println.md)
  - [Debug and Display](formatted-output/debug-display.md)
  - [formating](formatted-output/formatting.md)
- [Lifetime](lifetime/intro.md)
  - [basic](lifetime/basic.md)
  - [&'static and T: 'static](lifetime/static.md)
  - [advanced](lifetime/advance.md)
- [Functional programing](functional-programing/intro.md)
  - [Closure](functional-programing/closure.md)
  - [Iterator](functional-programing/iterator.md)
- [newtype and DST](newtype-sized.md)
- [Smart pointers TODO](smart-pointers/intro.md)
  - [Box](smart-pointers/box.md)
  - [Deref](smart-pointers/deref.md)
  - [Drop](smart-pointers/drop.md)
  - [Rc and Arc](smart-pointers/rc-arc.md)
  - [Cell and RefCell](smart-pointers/cell-refcell.md)
- [Weak and Circle reference TODO](weak.md)
- [Self referential TODO](self-referential.md)
- [Threads TODO](threads/intro.md)
  - [Basic using](threads/basic-using.md)
  - [Message passing](threads/message-passing.md)
  - [Sync](threads/sync.md)
  - [Atomic](threads/atomic.md)
  - [Send and Sync](threads/send-sync.md)
- [Global variables TODO](global-variables.md)
- [Errors TODO](errors.md)
- [Unsafe doing](unsafe/intro.md)
  - [Inline assembly](unsafe/inline-asm.md)
- [Macro TODO](macro.md)
- [Tests TODO](tests/intro.md)
  - [Write Tests](tests/write-tests.md)
  - [Benchmark](tests/benchmark.md)
  - [Unit and Integration](tests/unit-integration.md)
  - [Assertions](tests/assertions.md)
- [Async/Await TODO](async/intro.md)
  - [async and await!](async/async-await.md)
  - [Future](async/future.md)
  - [Pin and Unpin](async/pin-unpin.md)
  - [Stream](async/stream.md)
  
- [Standard Library TODO](std/intro.md)
  - [String](std/String.md)

- [Fighting with Compiler](fight-compiler/intro.md)
  - [Borrowing](fight-compiler/borrowing.md)

================================================
FILE: en/src/about.md
================================================
# Rust By Practice


================================================
FILE: en/src/async/async-await.md
================================================
# async and await!


================================================
FILE: en/src/async/future.md
================================================
# Future


================================================
FILE: en/src/async/intro.md
================================================
# Async/Await


================================================
FILE: en/src/async/pin-unpin.md
================================================
# Pin and Unpin


================================================
FILE: en/src/async/stream.md
================================================
# Stream


================================================
FILE: en/src/basic-types/char-bool-unit.md
================================================
# Char, Bool and Unit

### Char
1. 🌟
```rust,editable

// Make it work
use std::mem::size_of_val;
fn main() {
    let c1 = 'a';
    assert_eq!(size_of_val(&c1),1); 

    let c2 = '中';
    assert_eq!(size_of_val(&c2),3); 

    println!("Success!");
} 
```

2. 🌟
```rust,editable

// Make it work
fn main() {
    let c1 = "中";
    print_char(c1);
} 

fn print_char(c : char) {
    println!("{}", c);
}
```

### Bool
3. 🌟
```rust,editable

// Make println! work
fn main() {
    let _f: bool = false;

    let t = true;
    if !t {
        println!("Success!");
    }
} 
```

4. 🌟
```rust,editable

// Make it work
fn main() {
    let f = true;
    let t = true && false;
    assert_eq!(t, f);

    println!("Success!");
}
```


### Unit type
5. 🌟🌟
```rust,editable

// Make it work, don't modify `implicitly_ret_unit` !
fn main() {
    let _v: () = ();

    let v = (2, 3);
    assert_eq!(v, implicitly_ret_unit());

    println!("Success!");
}

fn implicitly_ret_unit() {
    println!("I will return a ()");
}

// Don't use this one
fn explicitly_ret_unit() -> () {
    println!("I will return a ()");
}
```

6. 🌟🌟 What's the size of the unit type?
```rust,editable

// Modify `4` in assert to make it work
use std::mem::size_of_val;
fn main() {
    let unit: () = ();
    assert!(size_of_val(&unit) == 4);

    println!("Success!");
}
```

> You can find the solutions [here](https://github.com/sunface/rust-by-practice)(under the solutions path), but only use it when you need it


================================================
FILE: en/src/basic-types/functions.md
================================================
# Functions
1. 🌟🌟🌟
```rust,editable

fn main() {
    // Don't modify the following two lines!
    let (x, y) = (1, 2);
    let s = sum(x, y);

    assert_eq!(s, 3);

    println!("Success!");
}

fn sum(x, y: i32) {
    x + y;
}
```


2. 🌟
```rust,editable
fn main() {
   print();
}

// Replace i32 with another type
fn print() -> i32 {
   println!("Success!");
}
```


3. 🌟🌟🌟

```rust,editable
// Solve it in two ways
// DON'T let `println!` work
fn main() {
    never_return();

    println!("Failed!");
}

fn never_return() -> ! {
    // Implement this function, don't modify the fn signatures
    
}
```

### Diverging functions 
Diverging functions never return to the caller, so they may be used in places where a value of any type is expected.

4. 🌟🌟
```rust,editable

fn main() {
    println!("Success!");
}

fn get_option(tp: u8) -> Option<i32> {
    match tp {
        1 => {
            // TODO
        }
        _ => {
            // TODO
        }
    };
    
    // Rather than returning a None, we use a diverging function instead
    never_return_fn()
}

// IMPLEMENT this function in THREE ways
fn never_return_fn() -> ! {
    
}
```

5. 🌟🌟
```rust,editable

fn main() {
    // FILL in the blank
    let b = __;

    let _v = match b {
        true => 1,
        // Diverging functions can also be used in match expression to replace a value of any value
        false => {
            println!("Success!");
            panic!("we have no value for `false`, but we can panic");
        }
    };

    println!("Exercise Failed if printing out this line!");
}
```

> You can find the solutions [here](https://github.com/sunface/rust-by-practice/blob/master/solutions/basic-types/functions.md)(under the solutions path), but only use it when you need it


================================================
FILE: en/src/basic-types/intro.md
================================================
# Basic Types
Learning resources: 
- English: [Rust Book 3.2 and 3.3](https://doc.rust-lang.org/book/ch03-02-data-types.html)
- 简体中文: [Rust语言圣经 - 基本类型](https://course.rs/basic/base-type/index.html)



================================================
FILE: en/src/basic-types/numbers.md
================================================
# Numbers

### Integer

1. 🌟 

> Tips: If we don't explicitly assign a type to a variable, then the compiler will infer one for us.

```rust,editable

// Remove something to make it work
fn main() {
    let x: i32 = 5;
    let mut y: u32 = 5;

    y = x;
    
    let z = 10; // Type of z ? 

    println!("Success!");
}
```

2. 🌟
```rust,editable

// Fill the blank
fn main() {
    let v: u16 = 38_u8 as __;

    println!("Success!");
}
```

3. 🌟🌟🌟  

> Tips: If we don't explicitly assign a type to a variable, then the compiler will infer one for us.

```rust,editable

// Modify `assert_eq!` to make it work
fn main() {
    let x = 5;
    assert_eq!("u32".to_string(), type_of(&x));

    println!("Success!");
}

// Get the type of given variable, return a string representation of the type  , e.g "i8", "u8", "i32", "u32"
fn type_of<T>(_: &T) -> String {
    format!("{}", std::any::type_name::<T>())
}
```

4. 🌟🌟 
```rust,editable

// Fill the blanks to make it work
fn main() {
    assert_eq!(i8::MAX, __); 
    assert_eq!(u8::MAX, __); 

    println!("Success!");
}
```

5. 🌟🌟 
```rust,editable

// Fix errors and panics to make it work
fn main() {
   let v1 = 251_u8 + 8;
   let v2 = i8::checked_add(251, 8).unwrap();
   println!("{},{}",v1,v2);
}
```

6. 🌟🌟
```rust,editable

// Modify `assert!` to make it work
fn main() {
    let v = 1_024 + 0xff + 0o77 + 0b1111_1111;
    assert!(v == 1579);

    println!("Success!");
}
```


### Floating-Point
7. 🌟

```rust,editable

// Fill the blank to make it work
fn main() {
    let x = 1_000.000_1; // ?
    let y: f32 = 0.12; // f32
    let z = 0.01_f64; // f64

    assert_eq!(type_of(&x), "__".to_string());
    println!("Success!");
}

fn type_of<T>(_: &T) -> String {
    format!("{}", std::any::type_name::<T>())
}
```

8. 🌟🌟 Make it work in two distinct ways

```rust,editable

fn main() {
    assert!(0.1+0.2==0.3);

    println!("Success!");
}
```

### Range
9. 🌟🌟 Two goals: 1. Modify `assert!` to make it work 2. Make `println!` output list of numbers between 97 and 122

```rust,editable
fn main() {
    let mut sum = 0;
    for i in -3..2 {
        sum += i
    }

    assert!(sum == -3);

    for c in 'a'..='z' {
        println!("{}",c);
    }
}
```

10. 🌟🌟 
```rust,editable

// Fill the blanks
use std::ops::{Range, RangeInclusive};
fn main() {
    assert_eq!((1..__), Range{ start: 1, end: 5 });
    assert_eq!((1..__), RangeInclusive::new(1, 5));

    println!("Success!");
}
```

### Computations

11. 🌟 
```rust,editable

// Fill the blanks and fix the errors
fn main() {
    // Integer addition
    assert!(1u32 + 2 == __);

    // Integer subtraction
    assert!(1i32 - 2 == __);
    assert!(1u8 - 2 == -1); 
    
    assert!(3 * 50 == __);

    assert!(9.6 / 3.2 == 3.0); // error ! make it work

    assert!(24 % 5 == __);
    // Short-circuiting boolean logic
    assert!(true && false == __);
    assert!(true || false == __);
    assert!(!true == __);

    // Bitwise operations
    println!("0011 AND 0101 is {:04b}", 0b0011u32 & 0b0101);
    println!("0011 OR 0101 is {:04b}", 0b0011u32 | 0b0101);
    println!("0011 XOR 0101 is {:04b}", 0b0011u32 ^ 0b0101);
    println!("1 << 5 is {}", 1u32 << 5);
    println!("0x80 >> 2 is 0x{:x}", 0x80u32 >> 2);
}
```

> You can find the solutions [here](https://github.com/sunface/rust-by-practice/blob/master/solutions/basic-types/numbers.md)(under the solutions path), but only use it when you need it


================================================
FILE: en/src/basic-types/statements-expressions.md
================================================
# Statements and Expressions

### Examples
```rust,editable
fn main() {
    let x = 5u32;

    let y = {
        let x_squared = x * x;
        let x_cube = x_squared * x;

        // This expression will be assigned to `y`
        x_cube + x_squared + x
    };

    let z = {
        // The semicolon suppresses this expression and `()` is assigned to `z`
        2 * x;
    };

    println!("x is {:?}", x);
    println!("y is {:?}", y);
    println!("z is {:?}", z);
}
```

### Exercises
1. 🌟🌟
```rust,editable
// Make it work with two ways
fn main() {
   let v = {
       let mut x = 1;
       x += 2
   };

   assert_eq!(v, 3);

   println!("Success!");
}
```

2. 🌟
```rust,editable

fn main() {
   let v = (let x = 3);

   assert!(v == 3);

   println!("Success!");
}
```

3. 🌟
```rust,editable

fn main() {
    let s = sum(1 , 2);
    assert_eq!(s, 3);

    println!("Success!");
}

fn sum(x: i32, y: i32) -> i32 {
    x + y
}
```

> You can find the solutions [here](https://github.com/sunface/rust-by-practice)(under the solutions path), but only use it when you need it


================================================
FILE: en/src/circle-reference/intro.md
================================================
# Circle reference and Self referential


================================================
FILE: en/src/collections/hashmap.md
================================================
# HashMap
Where vectors store values by an integer index, HashMaps store values by key. It is a hash map implemented with quadratic probing and SIMD lookup. By default, `HashMap` uses a hashing algorithm selected to provide resistance against HashDoS attacks.

The default hashing algorithm is currently `SipHash 1-3`, though this is subject to change at any point in the future. While its performance is very competitive for medium sized keys, other hashing algorithms will outperform it for small keys such as integers as well as large keys such as long strings, though those algorithms will typically not protect against attacks such as HashDoS.

The hash table implementation is a Rust port of Google’s [SwissTable](https://abseil.io/blog/20180927-swisstables). The original C++ version of SwissTable can be found [here](https://github.com/abseil/abseil-cpp/blob/master/absl/container/internal/raw_hash_set.h), and this [CppCon talk](https://www.youtube.com/watch?v=ncHmEUmJZf4) gives an overview of how the algorithm works.


### Basic Operations
1. 🌟🌟

```rust,editable

// FILL in the blanks and FIX the errors
use std::collections::HashMap;
fn main() {
    let mut scores = HashMap::new();
    scores.insert("Sunface", 98);
    scores.insert("Daniel", 95);
    scores.insert("Ashley", 69.0);
    scores.insert("Katie", "58");

    // Get returns an Option<&V>
    let score = scores.get("Sunface");
    assert_eq!(score, Some(98));

    if scores.contains_key("Daniel") {
        // Indexing returns a value V
        let score = scores["Daniel"];
        assert_eq!(score, __);
        scores.remove("Daniel");
    }

    assert_eq!(scores.len(), __);

    for (name, score) in scores {
        println!("The score of {} is {}", name, score);
    }
}
```

2. 🌟🌟
```rust,editable

use std::collections::HashMap;
fn main() {
    let teams = [
        ("Chinese Team", 100),
        ("American Team", 10),
        ("France Team", 50),
    ];

    let mut teams_map1 = HashMap::new();
    for team in &teams {
        teams_map1.insert(team.0, team.1);
    }

    // IMPLEMENT team_map2 in two ways
    // Tips: one of the approaches is to use `collect` method
    let teams_map2...

    assert_eq!(teams_map1, teams_map2);

    println!("Success!");
}
```

3. 🌟🌟
```rust,editable

// FILL in the blanks
use std::collections::HashMap;
fn main() {
    // Type inference lets us omit an explicit type signature (which
    // would be `HashMap<&str, u8>` in this example).
    let mut player_stats = HashMap::new();

    // Insert a key only if it doesn't already exist
    player_stats.entry("health").or_insert(100);

    assert_eq!(player_stats["health"], __);

    // Insert a key using a function that provides a new value only if it
    // doesn't already exist
    player_stats.entry("health").or_insert_with(random_stat_buff);
    assert_eq!(player_stats["health"], __);

    // Ensures a value is in the entry by inserting the default if empty, and returns
    // a mutable reference to the value in the entry.
    let health = player_stats.entry("health").or_insert(50);
    assert_eq!(health, __);
    *health -= 50;
    assert_eq!(*health, __);

    println!("Success!");
}

fn random_stat_buff() -> u8 {
    // Could actually return some random value here - let's just return
    // some fixed value for now
    42
}
```

### Requirements of HashMap key
Any type that implements the `Eq` and `Hash` traits can be a key in `HashMap`. This includes:

- `bool` (though not very useful since there is only two possible keys)
- `int`, `uint`, and all variations thereof
- `String` and `&str` (tips: you can have a `HashMap` keyed by `String` and call `.get()` with an `&str`)
  
Note that `f32` and `f64` do not implement `Hash`, likely because [floating-point precision](https://en.wikipedia.org/wiki/Floating-point_arithmetic#Accuracy_problems) errors would make using them as hashmap keys horribly error-prone.

All collection classes implement `Eq` and `Hash` if their contained type also respectively implements `Eq` and `Hash`. For example, `Vec<T>` will implement `Hash` if `T`implements `Hash`.

4. 🌟🌟
```rust,editable

// FIX the errors
// Tips: `derive` is usually a good way to implement some common used traits
use std::collections::HashMap;

struct Viking {
    name: String,
    country: String,
}

impl Viking {
    /// Creates a new Viking.
    fn new(name: &str, country: &str) -> Viking {
        Viking {
            name: name.to_string(),
            country: country.to_string(),
        }
    }
}

fn main() {
    // Use a HashMap to store the vikings' health points.
    let vikings = HashMap::from([
        (Viking::new("Einar", "Norway"), 25),
        (Viking::new("Olaf", "Denmark"), 24),
        (Viking::new("Harald", "Iceland"), 12),
    ]);

    // Use derived implementation to print the status of the vikings.
    for (viking, health) in &vikings {
        println!("{:?} has {} hp", viking, health);
    }
}
```

### Capacity
Like vectors, HashMaps are growable, but HashMaps can also shrink themselves when they have excess space. You can create a `HashMap` with a certain starting capacity using `HashMap::with_capacity(uint)`, or use `HashMap::new()` to get a HashMap with a default initial capacity (recommended).

#### Example
```rust,editable

use std::collections::HashMap;
fn main() {
    let mut map: HashMap<i32, i32> = HashMap::with_capacity(100);
    map.insert(1, 2);
    map.insert(3, 4);
    // Indeed ,the capacity of HashMap is not 100, so we can't compare the equality here.
    assert!(map.capacity() >= 100);

    // Shrinks the capacity of the map with a lower limit. It will drop
    // down no lower than the supplied limit while maintaining the internal rules
    // and possibly leaving some space in accordance with the resize policy.

    map.shrink_to(50);
    assert!(map.capacity() >= 50);

    // Shrinks the capacity of the map as much as possible. It will drop
    // down as much as possible while maintaining the internal rules
    // and possibly leaving some space in accordance with the resize policy.
    map.shrink_to_fit();
    assert!(map.capacity() >= 2);
    println!("Success!");
}
```

### Ownership
For types that implement the `Copy` trait, like `i32` , the values are copied into `HashMap`. For owned values like `String`, the values will be moved and `HashMap` will be the owner of those values.

5. 🌟🌟
```rust,editable
// FIX the errors with least changes
// DON'T remove any code line
use std::collections::HashMap;
fn main() {
  let v1 = 10;
  let mut m1 = HashMap::new();
  m1.insert(v1, v1);
  println!("v1 is still usable after inserting to hashmap : {}", v1);

  let v2 = "hello".to_string();
  let mut m2 = HashMap::new();
  // Ownership moved here
  m2.insert(v2, v1);
    
  assert_eq!(v2, "hello");

  println!("Success!");
}
```

### Third-party Hash libs
If the performance of `SipHash 1-3` doesn't meet your requirements, you can find replacements in crates.io or github.com.

The usage of third-party hash looks like this:
```rust
use std::hash::BuildHasherDefault;
use std::collections::HashMap;
// Introduce a third party hash function
use twox_hash::XxHash64;


let mut hash: HashMap<_, _, BuildHasherDefault<XxHash64>> = Default::default();
hash.insert(42, "the answer");
assert_eq!(hash.get(&42), Some(&"the answer"));
```



================================================
FILE: en/src/collections/intro.md
================================================
# Collection Types
Learning resources: 
- English: [Rust Book Chapter 8](https://doc.rust-lang.org/book/ch08-00-common-collections.html)
- 简体中文: [Rust语言圣经 - 集合类型](https://course.rs/basic/collections/intro.html)



================================================
FILE: en/src/collections/string.md
================================================
# String
`std::string::String` is a UTF-8 encoded, growable string. It is the most common string type we used in daily development, it also has ownership over the string contents.

### Basic operations
1. 🌟🌟
```rust,editable

// FILL in the blanks and FIX errors
// 1. Don't use `to_string()`
// 2. Don't add/remove any code line
fn main() {
    let mut s: String = "hello, ";
    s.push_str("world".to_string());
    s.push(__);

    move_ownership(s);

    assert_eq!(s, "hello, world!");

    println!("Success!");
}

fn move_ownership(s: String) {
    println!("ownership of \"{}\" is moved here!", s)
}
```

### String and &str
A `String` is stored as a vector of bytes (`Vec<u8>`), but guaranteed to always be a valid UTF-8 sequence. `String` is heap allocated, growable and not null terminated.

`&str` is a slice (`&[u8]`) that always points to a valid UTF-8 sequence, and can be used to view into a String, just like `&[T]` is a view into `Vec<T>`.

2. 🌟🌟
```rust,editable
// FILL in the blanks
fn main() {  
   let mut s = String::from("hello, world");

   let slice1: &str = __; // In two ways
   assert_eq!(slice1, "hello, world");

   let slice2 = __;
   assert_eq!(slice2, "hello");

   let slice3: __ = __; 
   slice3.push('!');
   assert_eq!(slice3, "hello, world!");

   println!("Success!");
}
```

3. 🌟🌟
```rust,editable

// Question: how many heap allocations are happening here?
// Your answer: 
fn main() {  
    // Create a String type based on `&str`
    // The type of string literals is `&str`
   let s: String = String::from("hello, world!");

   // Create a slice point to String `s`
   let slice: &str = &s;

   // Create a String type based on the recently created slice
   let s: String = slice.to_string();

   assert_eq!(s, "hello, world!");

   println!("Success!");
}
```

### UTF-8 & Indexing
Strings are always valid UTF-8. This has a few implications:

- The first of which is that if you need a non-UTF-8 string, consider [OsString](https://doc.rust-lang.org/stable/std/ffi/struct.OsString.html). It is similar, but without the UTF-8 constraint. 
- The second implication is that you cannot index into a String.

Indexing is intended to be a constant-time operation, but UTF-8 encoding does not allow us to do this. Furthermore, it’s not clear what sort of thing the index should return: a byte, a codepoint, or a grapheme cluster. The bytes and chars methods return iterators over the first two, respectively.

4. 🌟🌟🌟 You can't use index to access a char in a string, but you can use slice `&s1[start..end]`.

```rust,editable

// FILL in the blank and FIX errors
fn main() {
    let s = String::from("hello, 世界");
    let slice1 = s[0]; //tips: `h` only takes 1 byte in UTF8 format
    assert_eq!(slice1, "h");

    let slice2 = &s[3..5]; // Tips: `中`  takes 3 bytes in UTF8 format
    assert_eq!(slice2, "世");
    
    // Iterate through all chars in s
    for (i, c) in s.__ {
        if i == 7 {
            assert_eq!(c, '世')
        }
    }

    println!("Success!");
}
```


#### UTF8_slice
You can use [utf8_slice](https://docs.rs/utf8_slice/1.0.0/utf8_slice/fn.slice.html) to slice UTF8 string, it can index chars instead of bytes.

**Example**
```rust
use utf8_slice;
fn main() {
   let s = "The 🚀 goes to the 🌑!";

   let rocket = utf8_slice::slice(s, 4, 5);
   // Will equal "🚀"
}
```


5. 🌟🌟🌟
> Tips: maybe you need `from_utf8` method

```rust,editable

// FILL in the blanks
fn main() {
    let mut s = String::new();
    __;

    // Some bytes, in a vector
    let v = vec![104, 101, 108, 108, 111];

    // Turn a byte's vector into a String
    let s1 = __;
    
    
    assert_eq!(s, s1);

    println!("Success!");
}
```

### Representation
A String is made up of three components: a pointer to some bytes, a length, and a capacity. 

The pointer points to an internal buffer String uses to store its data. The length is the number of bytes currently stored in the buffer( always stored on the heap ), and the capacity is the size of the buffer in bytes. As such, the length will always be less than or equal to the capacity.

6. 🌟🌟 If a String has enough capacity, adding elements to it will not re-allocate
```rust,editable

// Modify the code below to print out: 
// 25
// 25
// 25
// Here, there’s no need to allocate more memory inside the loop.
fn main() {
    let mut s = String::new();

    println!("{}", s.capacity());

    for _ in 0..2 {
        s.push_str("hello");
        println!("{}", s.capacity());
    }

    println!("Success!");
}
```

7. 🌟🌟🌟
```rust,editable

// FILL in the blanks
use std::mem;

fn main() {
    let story = String::from("Rust By Practice");

    // Prevent automatically dropping of the String's data
    let mut story = mem::ManuallyDrop::new(story);

    let ptr = story.__();
    let len = story.__();
    let capacity = story.__();

    assert_eq!(16, len);

    // We can rebuild a String out of ptr, len, and capacity. This is all
    // unsafe because we are responsible for making sure the components are
    // valid:
    let s = unsafe { String::from_raw_parts(ptr, len, capacity) };

    assert_eq!(*story, s);

    println!("Success!");
}
```


### Common methods
More exercises of String methods can be found [here](../std/String.md).

> You can find the solutions [here](https://github.com/sunface/rust-by-practice)(under the solutions path), but only use it when you need it

================================================
FILE: en/src/collections/vector.md
================================================
# Vector
Vectors are resizable arrays. Like slices, their size is not known at compile time, but they can grow or shrink at any time. 

### Basic Operations
1. 🌟🌟🌟
```rust,editable

fn main() {
    let arr: [u8; 3] = [1, 2, 3];
    
    let v = Vec::from(arr);
    is_vec(&v);

    let v = vec![1, 2, 3];
    is_vec(&v);

    // vec!(..) and vec![..] are same macros, so
    let v = vec!(1, 2, 3);
    is_vec(&v);
    
    // In code below, v is Vec<[u8; 3]> , not Vec<u8>
    // USE Vec::new and `for` to rewrite the below code 
    let v1 = vec!(arr);
    is_vec(&v1);
 
    assert_eq!(v, v1);

    println!("Success!");
}

fn is_vec(v: &Vec<u8>) {}
```



2. 🌟🌟 A Vec can be extended with `extend` method
```rust,editable

// FILL in the blank
fn main() {
    let mut v1 = Vec::from([1, 2, 4]);
    v1.pop();
    v1.push(3);
    
    let mut v2 = Vec::new();
    v2.__;

    assert_eq!(v1, v2);

    println!("Success!");
}
```

### Turn X Into Vec
3. 🌟🌟🌟
```rust,editable

// FILL in the blanks
fn main() {
    // Array -> Vec
    // impl From<[T; N]> for Vec
    let arr = [1, 2, 3];
    let v1 = __(arr);
    let v2: Vec<i32> = arr.__();
 
    assert_eq!(v1, v2);
 
    
    // String -> Vec
    // impl From<String> for Vec
    let s = "hello".to_string();
    let v1: Vec<u8> = s.__();

    let s = "hello".to_string();
    let v2 = s.into_bytes();
    assert_eq!(v1, v2);

    // impl<'_> From<&'_ str> for Vec
    let s = "hello";
    let v3 = Vec::__(s);
    assert_eq!(v2, v3);

    println!("Success!");
 }
```

### Indexing
4. 🌟🌟🌟
```rust,editable

// FIX the error and IMPLEMENT the code
fn main() {
    let mut v = Vec::from([1, 2, 3]);
    for i in 0..5 {
        println!("{:?}", v[i])
    }

    for i in 0..5 {
       // IMPLEMENT the code here...
    }
    
    assert_eq!(v, vec![2, 3, 4, 5, 6]);

    println!("Success!");
}
```


### Slicing
Immutable or mutable slices of Vecs can be taken, using `&` or `&mut`, respectively.

In Rust, it’s more common to pass immutable slices as arguments rather than vectors when you just want to provide read access, as this is more flexible (no move) and efficient (no copy). The same goes for `String` and `&str`.

5. 🌟🌟
```rust,editable

// FIX the errors
fn main() {
    let mut v = vec![1, 2, 3];

    let slice1 = &v[..];
    // Out of bounds will cause a panic
    // You must use `v.len` here
    let slice2 = &v[0..4];
    
    assert_eq!(slice1, slice2);
    
    // A slice can also be mutable, in which
    // case mutating it will mutate its underlying Vec.
    // Note: slice and &Vec are different
    let vec_ref: &mut Vec<i32> = &mut v;
    (*vec_ref).push(4);
    let slice3 = &mut v[0..3];
    slice3[3] = 42;

    assert_eq!(slice3, &[1, 2, 3, 42]);
    assert_eq!(v, &[1, 2, 3, 42]);

    println!("Success!");
}
```
### Capacity
The capacity of a vector is the amount of space allocated for any future elements that will be added onto the vector. This is not to be confused with the length of a vector, which specifies the number of actual elements within the vector. If a vector’s length exceeds its capacity, its capacity will automatically be increased, but its elements will have to be reallocated.

For example, a vector with capacity 10 and length 0 would be an empty vector with space for 10 more elements. Pushing 10 or fewer elements onto the vector will not change its capacity or cause reallocation to occur. However, if the vector’s length is increased to 11, it will have to reallocate, which can be slow. For this reason, it is recommended to use `Vec::with_capacity `whenever possible to specify how big the vector is expected to get.

6. 🌟🌟
```rust,editable
// FIX the errors
fn main() {
    let mut vec = Vec::with_capacity(10);

    // The vector contains no items, even though it has capacity for more
    assert_eq!(vec.len(), __);
    assert_eq!(vec.capacity(), 10);

    // These are all done without reallocating...
    for i in 0..10 {
        vec.push(i);
    }
    assert_eq!(vec.len(), __);
    assert_eq!(vec.capacity(), __);

    // ...but this may make the vector reallocate
    vec.push(11);
    assert_eq!(vec.len(), 11);
    assert!(vec.capacity() >= 11);


    // Fill in an appropriate value to make the `for` done without reallocating 
    let mut vec = Vec::with_capacity(__);
    for i in 0..100 {
        vec.push(i);
    }

    assert_eq!(vec.len(), __);
    assert_eq!(vec.capacity(), __);
    
    println!("Success!");
}
```

### Store distinct types in Vector
The elements in a vector must be the same type, for example , the code below will cause an error:
```rust
fn main() {
   let v = vec![1, 2.0, 3];
}
```

But we can use enums or trait objects to store distinct types.

7. 🌟🌟
```rust,editable
#[derive(Debug)]
enum IpAddr {
    V4(String),
    V6(String),
}
fn main() {
    // FILL in the blank
    let v : Vec<IpAddr>= __;
    
    // Comparing two enums need to derive the PartialEq trait
    assert_eq!(v[0], IpAddr::V4("127.0.0.1".to_string()));
    assert_eq!(v[1], IpAddr::V6("::1".to_string()));

    println!("Success!");
}
```

8. 🌟🌟
```rust,editable
trait IpAddr {
    fn display(&self);
}

struct V4(String);
impl IpAddr for V4 {
    fn display(&self) {
        println!("ipv4: {:?}",self.0)
    }
}
struct V6(String);
impl IpAddr for V6 {
    fn display(&self) {
        println!("ipv6: {:?}",self.0)
    }
}

fn main() {
    // FILL in the blank
    let v: __= vec![
        Box::new(V4("127.0.0.1".to_string())),
        Box::new(V6("::1".to_string())),
    ];

    for ip in v {
        ip.display();
    }
}
```


================================================
FILE: en/src/comments-docs.md
================================================
# Comments and Docs
Every program requires comments:


## Comments
- Regular comments which are ignored by the compiler:
  - `// Line comment, which goes to the end of the line`
  - `/* Block comment, which goes to the end of the closing delimiter */`


### Examples
```rust
fn main() {
    // This is an example of a line comment
    // There are two slashes at the beginning of the line
    // And nothing written inside these will be read by the compiler

    // println!("Hello, world!");

    // Run it. See? Now try deleting the two slashes, and run it again.

    /* 
     * This is another type of comment, a block comment. In general,
     * line comments are the recommended comment style. But
     * block comments are extremely useful for temporarily disabling
     * chunks of code. /* Block comments can be /* nested, */ */
     * so it takes only a few keystrokes to comment out everything
     * in this main() function. /*/*/* Try it yourself! */*/*/
     */

    /*
    Note: The previous column of `*` was entirely for style. There's
    no actual need for it.
    */
}
```

### Exercises
1. 🌟🌟
```rust,editable

/* Make it work, only using comments! */
fn main() {
    todo!();
    unimplemented!();

    assert_eq!(6, 5 + 3 + 2 + 1 )
}
```


## Doc Comments
- Doc comments which are parsed into HTML and supported `Markdown`
  - `/// Generate library docs for the following item`
  - `//! Generate library docs for the eclosing item`

Before starting, we need to create a new package for practice: `cargo new --lib doc-comments`.


### Line doc comments `///` 
Add docs for function `add_one`
```rust
// in lib.rs

/// Add one to the given value and return the value
///
/// # Examples
///
/// ```
/// let arg = 5;
/// let answer = my_crate::add_one(arg);
///
/// assert_eq!(6, answer);
/// ```
pub fn add_one(x: i32) -> i32 {
    x + 1
}
```

### Cargo doc
We can use `cargo doc --open` to generate html files and open them in the browser.

### Block doc comments `/** ... */`
Add docs for function `add_two`:
```rust
/** Add two to the given value and return a new value

# Examples

let arg = 5;
let answer = my_crate::add_two(arg);

assert_eq!(7, answer);

*/
pub fn add_two(x: i32) -> i32 {
    x + 2
}
```

### Doc comments for crate and module
We can also add doc comments for our crates and modules.

Firstly, let's add some doc comments for our library crate:

> Note: We must place crates and module comments at the top of crate root or module file.
```rust
//! # Doc comments
//! 
//! A library for showing how to use doc comments

// in lib.rs
pub mod compute;
```

You can also use block comments to achieve this:
```rust
/*! # Doc comments

 A library for showing how to use doc comments */
```

Next, create a new module file `src/compute.rs`, and add following comments to it:
```rust
//! //! Do some complicated arithmetic that you can't do by yourself

// in compute.rs
```

Then run `cargo doc --open` and see the results.


### Doc tests
The doc comments of `add_one` and `add_two` contain two example code blocks.

The examples can not only demonstrate how to use your library, but also running as test with `cargo test` command.

2. 🌟🌟 But there are errors in the two examples, please fix them, and running with `cargo test` to get following result: 
```shell
running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

   Doc-tests doc-comments

running 2 tests
test src/lib.rs - add_one (line 11) ... ok
test src/lib.rs - add_two (line 26) ... ok

test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.55s
```

3. 🌟🌟 Sometimes we expect an example to be panic, add following code to `src/compute.rs` and make the `cargo test` passed.

> You can only modify the comments, DON'T modify `fn div`

```rust
// in src/compute.rs

/// # Panics
///
/// The function panics if the second argument is zero.
///
/// ```rust,should_panic
/// // panics on division by zero
/// doc_comments::compute::div(10, 0);
/// ```
pub fn div(a: i32, b: i32) -> i32 {
    if b == 0 {
        panic!("Divide-by-zero error");
    }

    a / b
}
```

4. 🌟🌟 Sometimes we want to hide the doc comments, but keep the doc tests.

Add following code to `src/compute.rs` ,

```rust
// in src/compute.rs

/// ```
/// # fn try_main() -> Result<(), String> {
/// # let res = doc_comments::compute::try_div(10, 0)?;
/// # Ok(()) // returning from try_main
/// # }
/// # fn main() { 
/// #    try_main().unwrap();
/// #
/// # }
/// ```
pub fn try_div(a: i32, b: i32) -> Result<i32, String> {
    if b == 0 {
        Err(String::from("Divide-by-zero"))
    } else {
        Ok(a / b)
    }
}
```

and modify this code to achieve two goals:

- The doc comments must not be presented in html files generated by `cargo doc --open`
- run the tests, you should see results as below:

```shell
running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

   Doc-tests doc-comments

running 4 tests
test src/compute.rs - compute::div (line 7) ... ok
test src/lib.rs - add_two (line 27) ... ok
test src/lib.rs - add_one (line 11) ... ok
test src/compute.rs - compute::try_div (line 20) ... ok

test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.51s
```

### Code navigation
Rust provide a very powerful feature for us, that is code navigation in doc comments.

Add following code to `src/lib.rs`:
```rust
// in lib.rs

/// Add three to the given value and return a [`Option`] type
pub fn add_three(x: i32) -> Option<i32> {
    Some(x + 3)
}
```

Besides jump into the standard library, you can also jump to another module in the package.

```rust
// in lib.rs

mod a {
    /// Add four to the given value and return a [`Option`] type
    /// [`crate::MySpecialFormatter`]
    pub fn add_four(x: i32) -> Option<i32> {
        Some(x + 4)
    }
}

struct MySpecialFormatter;
```

### Doc attributes
Below are a few examples of the most common `#[doc]` attributes used with `rustdoc`.

### `inline`

Used to inline docs, instead of linking out to separate page.

```rust,ignore
#[doc(inline)]
pub use bar::Bar;

/// bar docs
mod bar {
    /// the docs for Bar
    pub struct Bar;
}
```

### `no_inline`

Used to prevent linking out to separate page or anywhere.

```rust,ignore
// Example from libcore/prelude
#[doc(no_inline)]
pub use crate::mem::drop;
```

### `hidden`

Using this tells `rustdoc` not to include this in documentation:

```rust,editable,ignore
// Example from the futures-rs library
#[doc(hidden)]
pub use self::async_await::*;
```

For documentation, `rustdoc` is widely used by the community. It's what is used to generate the [std library docs](https://doc.rust-lang.org/std/).


### Full Code
The full code of package `doc-comments` is [here](https://github.com/sunface/rust-by-practice/tree/master/practices/doc-comments).


================================================
FILE: en/src/compound-types/array.md
================================================
# Array
The type of array is `[T; Length]`, as you can see, array's length is part of their type signature. So their length must be known at compile time.

For example, you cant initialize an array like below:
```rust
fn init_arr(n: i32) {
    let arr = [1; n];
}
```

This will cause an error, because the compiler has no idea of the exact size of the array at compile time.

1. 🌟 
```rust,editable

fn main() {
    // Fill the blank with proper array type
    let arr: __ = [1, 2, 3, 4, 5];

    // Modify the code below to make it work
    assert!(arr.len() == 4);

    println!("Success!");
}
```

2. 🌟🌟
```rust,editable

fn main() {
    // We can ignore parts of the array type or even the whole type, let the compiler infer it for us
    let arr0 = [1, 2, 3];
    let arr: [_; 3] = ['a', 'b', 'c'];
    
    // Fill the blank
    // Arrays are stack allocated, `std::mem::size_of_val` returns the bytes which an array occupies
    // A char takes 4 bytes in Rust: Unicode char
    assert!(std::mem::size_of_val(&arr) == __);

    println!("Success!");
}
```

3. 🌟 All elements in an array can be initialized to the same value at once.

```rust,editable

fn main() {
    // Fill the blank
    let list: [i32; 100] = __ ;

    assert!(list[0] == 1);
    assert!(list.len() == 100);

    println!("Success!");
}
```

4. 🌟 All elements in an array must be of the same type
```rust,editable

fn main() {
    // Fix the error
    let _arr = [1, 2, '3'];

    println!("Success!");
}
```

5. 🌟 Indexing starts at 0.
```rust,editable

fn main() {
    let arr = ['a', 'b', 'c'];
    
    let ele = arr[1]; // Only modify this line to make the code work!

    assert!(ele == 'a');

    println!("Success!");
}
```

6. 🌟 Out of bounds indexing causes `panic`.
```rust,editable

// Fix the error
fn main() {
    let names = [String::from("Sunfei"), "Sunface".to_string()];
    
    // `Get` returns an Option<&T>, it's safe to use
    let name0 = names.get(0).unwrap();

    // But indexing is not safe
    let _name1 = &names[2];

    println!("Success!");
}

```

> You can find the solutions [here](https://github.com/sunface/rust-by-practice/blob/master/solutions/compound-types/array.md)(under the solutions path), but only use it when you need it


================================================
FILE: en/src/compound-types/enum.md
================================================
# Enum
1. 🌟🌟 Enums can be created with explicit discriminator.

```rust,editable

// Fix the errors
enum Number {
    Zero,
    One,
    Two,
}

enum Number1 {
    Zero = 0,
    One,
    Two,
}

// C-like enum
enum Number2 {
    Zero = 0.0,
    One = 1.0,
    Two = 2.0,
}


fn main() {
    // An enum variant can be converted to a integer by `as`
    assert_eq!(Number::One, Number1::One);
    assert_eq!(Number1::One, Number2::One);

    println!("Success!");
} 
```

2. 🌟 Each enum variant can hold its own data.
```rust,editable

// Fill in the blank
enum Message {
    Quit,
    Move { x: i32, y: i32 },
    Write(String),
    ChangeColor(i32, i32, i32),
}

fn main() {
    let msg1 = Message::Move{__}; // Instantiating with x = 1, y = 2 
    let msg2 = Message::Write(__); // Instantiating with "hello, world!"

    println!("Success!");
} 
```

3. 🌟🌟 We can get the data which an enum variant is holding by pattern match.
```rust,editable

// Fill in the blank and fix the error
enum Message {
    Quit,
    Move { x: i32, y: i32 },
    Write(String),
    ChangeColor(i32, i32, i32),
}

fn main() {
    let msg = Message::Move{x: 1, y: 2};

    if let Message::Move{__} = msg {
        assert_eq!(a, b);
    } else {
        panic!("NEVER LET THIS RUN!");
    }

    println!("Success!");
} 
```

4. 🌟🌟 

```rust,editable

// Fill in the blank and fix the errors
enum Message {
    Quit,
    Move { x: i32, y: i32 },
    Write(String),
    ChangeColor(i32, i32, i32),
}

fn main() {
    let msgs: __ = [
        Message::Quit,
        Message::Move{x:1, y:3},
        Message::ChangeColor(255,255,0)
    ];

    for msg in msgs {
        show_message(msg)
    }
} 

fn show_message(msg: Message) {
    println!("{}", msg);
}
```

5. 🌟🌟 Since there is no `null` in Rust, we have to use enum  `Option<T>`  to deal with the cases when the value is absent.
```rust,editable

// Fill in the blank to make the `println` work.
// Also add some code to prevent the `panic` from running.
fn main() {
    let five = Some(5);
    let six = plus_one(five);
    let none = plus_one(None);

    if let __ = six {
        println!("{}", n);

        println!("Success!");
    } 
        
    panic!("NEVER LET THIS RUN!");
} 

fn plus_one(x: Option<i32>) -> Option<i32> {
    match x {
        __ => None,
        __ => Some(i + 1),
    }
}
```


6. 🌟🌟🌟🌟 Implement a `linked-list` via enums.

```rust,editable

use crate::List::*;

enum List {
    // Cons: Tuple struct that wraps an element and a pointer to the next node
    Cons(u32, Box<List>),
    // Nil: A node that signifies the end of the linked list
    Nil,
}

// Methods can be attached to an enum
impl List {
    // Create an empty list
    fn new() -> List {
        // `Nil` has type `List`
        Nil
    }

    // Consume a list, and return the same list with a new element at its front
    fn prepend(self, elem: u32) -> __ {
        // `Cons` also has type List
        Cons(elem, Box::new(self))
    }

    // Return the length of the list
    fn len(&self) -> u32 {
        // `self` has to be matched, because the behavior of this method
        // depends on the variant of `self`
        // `self` has type `&List`, and `*self` has type `List`, matching on a
        // concrete type `T` is preferred over a match on a reference `&T`
        // After Rust 2018 you can use self here and tail (with no ref) below as well,
        // rust will infer &s and ref tail. 
        // See https://doc.rust-lang.org/edition-guide/rust-2018/ownership-and-lifetimes/default-match-bindings.html
        match *self {
            // Can't take ownership of the tail, because `self` is borrowed;
            // Instead take a reference to the tail
            Cons(_, ref tail) => 1 + tail.len(),
            // Base Case: An empty list has zero length
            Nil => 0
        }
    }

    // Return representation of the list as a (heap allocated) string
    fn stringify(&self) -> String {
        match *self {
            Cons(head, __ tail) => {
                // `format!` is similar to `print!`, but returns a heap
                // allocated string instead of printing to the console
                format!("{}, {}", head, tail.__())
            },
            Nil => {
                format!("Nil")
            },
        }
    }
}

fn main() {
    // Create an empty linked list
    let mut list = List::new();

    // Prepend some elements
    list = list.prepend(1);
    list = list.prepend(2);
    list = list.prepend(3);

    // Show the final state of the list
    println!("linked list has length: {}", list.len());
    println!("{}", list.stringify());
}
```

> You can find the solutions [here](https://github.com/sunface/rust-by-practice/blob/master/solutions/compound-types/enum.md)(under the solutions path), but only use it when you need it

================================================
FILE: en/src/compound-types/intro.md
================================================
# Compound Types
Learning resources: 
- English: [Rust Book 4.3, 5.1, 6.1, 8.2](https://doc.rust-lang.org/book/ch04-03-slices.html)
- 简体中文: [Rust语言圣经 - 复合类型](https://course.rs/basic/compound-type/intro.html)




================================================
FILE: en/src/compound-types/slice.md
================================================
# Slice
Slices are similar to arrays, but their length is not known at compile time, so you can't use slice directly.

1. 🌟🌟 Here, both `[i32]` and `str` are slice types, but directly using it will cause errors. You have to use the reference of the slice instead: `&[i32]`, `&str`.
```rust,editable

// Fix the errors, DON'T add new lines!
fn main() {
    let arr = [1, 2, 3];
    let s1: [i32] = arr[0..2];

    let s2: str = "hello, world" as str;

    println!("Success!");
}
```

A slice reference is a two-word object, for simplicity reasons, from now on we will use slice instead of `slice reference`. The first word is a pointer to the data, and the second word is the length of the slice. The word size is the same as usize, determined by the processor architecture, e.g. 64 bits on an x86-64. Slices can be used to borrow a section of an array, and have the type signature `&[T]`.

2. 🌟🌟🌟
```rust,editable

fn main() {
    let arr: [char; 3] = ['中', '国', '人'];

    let slice = &arr[..2];
    
    // Modify '8' to make it work
    // TIPS: slice( reference ) IS NOT an array, if it is an array, then `assert!` will be passed: Each of the two chars '中' and '国'  occupies 4 bytes, 2 * 4 = 8
    assert!(std::mem::size_of_val(&slice) == 8);

    println!("Success!");
}
```

3. 🌟🌟
```rust,editable

fn main() {
    let arr: [i32; 5] = [1, 2, 3, 4, 5];
    // Fill the blanks to make the code work
    let slice: __ = __;
    assert_eq!(slice, &[2, 3, 4]);

    println!("Success!");
}
```

### String slices
4. 🌟 
```rust,editable

fn main() {
    let s = String::from("hello");

    let slice1 = &s[0..2];
    // Fill the blank to make the code work, DON'T USE 0..2 again
    let slice2 = &s[__];

    assert_eq!(slice1, slice2);

    println!("Success!");
}
```

5. 🌟
```rust,editable

fn main() {
    let s = "你好,世界";
    // Modify this line to make the code work
    let slice = &s[0..2];

    assert!(slice == "你");

    println!("Success!");
}
```

6. 🌟🌟 `&String` can be implicitly converted into `&str`.
```rust,editable

// Fix errors
fn main() {
    let mut s = String::from("hello world");

    // Here, &s is `&String` type, but `first_letter` needs a `&str` type.
    // It works because `&String` can be implicitly converted to `&str. If you want to know more, this is called `Deref coercion`. 
    let letter = first_letter(&s);

    s.clear(); // error!

    println!("the first letter is: {}", letter);
}
fn first_letter(s: &str) -> &str {
    &s[..1]
}
```

> You can find the solutions [here](https://github.com/sunface/rust-by-practice/blob/master/solutions/compound-types/slice.md)(under the solutions path), but only use it when you need it


================================================
FILE: en/src/compound-types/string.md
================================================
# String
The type of string literal `"hello, world"` is `&str`, e.g `let s: &str = "hello, world"`.


### Str and &str
1. 🌟 We can't use `str` type in normal ways, but we can use `&str`.

```rust,editable

// Fix error without adding new line
fn main() {
    let s: str = "hello, world";

    println!("Success!");
}
```


2. 🌟🌟 We can only use `str` by boxing it, `&` can be used to convert `Box<str>` to `&str` 

```rust,editable

// Fix the error with at least two solutions
fn main() {
    let s: Box<str> = "hello, world".into();
    greetings(s)
}

fn greetings(s: &str) {
    println!("{}",s)
}
```

### String
`String` type is defined in std and stored as a vector of bytes (Vec<u8>), but guaranteed to always be a valid UTF-8 sequence. String is heap allocated, growable and not null terminated.

3. 🌟
```rust,editable

// Fill the blank
fn main() {
    let mut s = __;
    s.push_str("hello, world");
    s.push('!');

    assert_eq!(s, "hello, world!");

    println!("Success!");
}
```

4. 🌟🌟🌟
```rust,editable

// Fix all errors without adding newline
fn main() {
    let s = String::from("hello");
    s.push(',');
    s.push(" world");
    s += "!".to_string();

    println!("{}", s);
}
```

5. 🌟🌟 `replace` can be used to replace substring
```rust,editable

// Fill the blank
fn main() {
    let s = String::from("I like dogs");
    // Allocate new memory and store the modified string there
    let s1 = s.__("dogs", "cats");

    assert_eq!(s1, "I like cats");

    println!("Success!");
}
```

More `String` methods can be found under [String](https://doc.rust-lang.org/std/string/struct.String.html) module.

6. 🌟🌟 You can only concat a `String` with `&str`, and `String`'s ownership can be moved to another variable.

```rust,editable

// Fix errors without removing any line
fn main() {
    let s1 = String::from("hello,");
    let s2 = String::from("world!");
    let s3 = s1 + s2; 
    assert_eq!(s3, "hello,world!");
    println!("{}", s1);
}
```

### &str and String
Opposite to the seldom using of `str`, `&str` and `String` are used everywhere!

7. 🌟🌟 `&str` can be converted to `String` in two ways
```rust,editable

// Fix error with at least two solutions
fn main() {
    let s = "hello, world";
    greetings(s)
}

fn greetings(s: String) {
    println!("{}", s)
}
```

8. 🌟🌟 We can use `String::from` or `to_string` to convert a `&str` to `String`

```rust,editable

// Use two approaches to fix the error and without adding a new line
fn main() {
    let s = "hello, world".to_string();
    let s1: &str = s;

    println!("Success!");
}
```

### String escapes
9. 🌟 
```rust,editable
fn main() {
    // You can use escapes to write bytes by their hexadecimal values
    // Fill the blank below to show "I'm writing Rust"
    let byte_escape = "I'm writing Ru\x73__!";
    println!("What are you doing\x3F (\\x3F means ?) {}", byte_escape);

    // ...Or Unicode code points.
    let unicode_codepoint = "\u{211D}";
    let character_name = "\"DOUBLE-STRUCK CAPITAL R\"";

    println!("Unicode character {} (U+211D) is called {}",
                unicode_codepoint, character_name );

    let long_string = "String literals
                        can span multiple lines.
                        The linebreak and indentation here \
                         can be escaped too!";
    println!("{}", long_string);
}
```

10. 🌟🌟🌟 Sometimes there are just too many characters that need to be escaped or it's just much more convenient to write a string out as-is. This is where raw string literals come into play.

```rust,editable

/* Fill in the blank and fix the errors */
fn main() {
    let raw_str = r"Escapes don't work here: \x3F \u{211D}";
    // Modify above line to make it work
    assert_eq!(raw_str, "Escapes don't work here: ? ℝ");

    // If you need quotes in a raw string, add a pair of #s
    let quotes = r#"And then I said: "There is no escape!""#;
    println!("{}", quotes);

    // If you need "# in your string, just use more #s in the delimiter.
    // You can use up to 65535 #s.
    let delimiter = r###"A string with "# in it. And even "##!"###;
    println!("{}", delimiter);

    // Fill the blank
    let long_delimiter = __;
    assert_eq!(long_delimiter, "Hello, \"##\"");

    println!("Success!");
}
```

### Byte string
Want a string that's not UTF-8? (Remember, str and String must be valid UTF-8). Or maybe you want an array of bytes that's mostly text? Byte strings to the rescue!

**Example**:
```rust,editable
use std::str;

fn main() {
    // Note that this is not actually a `&str`
    let bytestring: &[u8; 21] = b"this is a byte string";

    // Byte arrays don't have the `Display` trait, so printing them is a bit limited
    println!("A byte string: {:?}", bytestring);

    // Byte strings can have byte escapes...
    let escaped = b"\x52\x75\x73\x74 as bytes";
    // ...But no unicode escapes
    // let escaped = b"\u{211D} Is not allowed";
    println!("Some escaped bytes: {:?}", escaped);


    // Raw byte strings work just like raw strings
    let raw_bytestring = br"\u{211D} is not escaped here";
    println!("{:?}", raw_bytestring);

    // Converting a byte array to `str` can fail
    if let Ok(my_str) = str::from_utf8(raw_bytestring) {
        println!("And the same as text: '{}'", my_str);
    }

    let _quotes = br#"You can also use "fancier" formatting, \
                    like with normal raw strings"#;

    // Byte strings don't have to be UTF-8
    let shift_jis = b"\x82\xe6\x82\xa8\x82\xb1\x82\xbb"; // "ようこそ" In SHIFT-JIS

    // But then they can't always be converted to `str`
    match str::from_utf8(shift_jis) {
        Ok(my_str) => println!("Conversion successful: '{}'", my_str),
        Err(e) => println!("Conversion failed: {:?}", e),
    };
}
```

A more detailed listing of the ways to write string literals and escape characters is given in the ['Tokens' chapter](https://doc.rust-lang.org/reference/tokens.html) of the Rust Reference.

### String index
11. 🌟🌟🌟 You can't use index to access a char in a string, but you can use slice `&s1[start..end]`.

```rust,editable

fn main() {
    let s1 = String::from("hi,中国");
    let h = s1[0]; // Modify this line to fix the error, tips: `h` only takes 1 byte in UTF8 format
    assert_eq!(h, "h");

    let h1 = &s1[3..5]; // Modify this line to fix the error, tips: `中`  takes 3 bytes in UTF8 format
    assert_eq!(h1, "中");

    println!("Success!");
}
```

### Operate on UTF8 string
12. 🌟
```rust,editable

fn main() {
    // Fill the blank to print each char in "你好,世界"
    for c in "你好,世界".__ {
        println!("{}", c)
    }
}
```

#### utf8_slice
You can use [utf8_slice](https://docs.rs/utf8_slice/1.0.0/utf8_slice/fn.slice.html) to slice UTF8 string, it can index chars instead of bytes.

**Example**
```rust
use utf8_slice;
fn main() {
    let s = "The 🚀 goes to the 🌑!";

    let rocket = utf8_slice::slice(s, 4, 5);
    // Will equal "🚀"
}
```

> You can find the solutions [here](https://github.com/sunface/rust-by-practice/blob/master/solutions/compound-types/string.md)(under the solutions path), but only use it when you need it


================================================
FILE: en/src/compound-types/struct.md
================================================
# Struct

### The types of structs
1. 🌟 We must specify concrete values for each of the fields in struct.
```rust,editable

// Fix the error
struct Person {
    name: String,
    age: u8,
    hobby: String
}
fn main() {
    let age = 30;
    let p = Person {
        name: String::from("sunface"),
        age,
    };

    println!("Success!");
} 
```


2. 🌟 Unit struct don't have any fields. It can be useful when you need to implement a trait on some type but don’t have any data that you want to store in the type itself. 
```rust,editable

struct Unit;
trait SomeTrait {
    // ...Some behaviors defined here.
}

// We don't care about what fields  are  in the Unit, but we care about its behaviors.
// So we use a struct with no fields and implement some behaviors for it
impl SomeTrait for Unit {  }
fn main() {
    let u = Unit;
    do_something_with_unit(u);

    println!("Success!");
} 

// Fill the blank to make the code work
fn do_something_with_unit(u: __) {   }
```

3. 🌟🌟🌟 Tuple struct looks similar to tuples, it has added meaning the struct name provides but has no named fields. It's useful when you want to give the whole tuple a name, but don't care about the fields's names.

```rust,editable

// Fix the error and fill the blanks
struct Color(i32, i32, i32);
struct Point(i32, i32, i32);
fn main() {
    let v = Point(__, __, __);
    check_color(v);

    println!("Success!");
}   

fn check_color(p: Color) {
    let (x, _, _) = p;
    assert_eq!(x, 0);
    assert_eq!(p.1, 127);
    assert_eq!(__, 255);
 }
```

### Operating on structs

4. 🌟 You can make a whole struct mutable when instantiating it, but Rust doesn't allow us to mark only certain fields as mutable.

```rust,editable

// Fill the blank and fix the error without adding/removing new line
struct Person {
    name: String,
    age: u8,
}
fn main() {
    let age = 18;
    let p = Person {
        name: String::from("sunface"),
        age,
    };

    // How can you believe sunface is only 18? 
    p.age = 30;

    // Fill the blank
    __ = String::from("sunfei");

    println!("Success!");
}
```

5. 🌟 Using *field init shorthand syntax* to reduce repetitions.
```rust,editable

// Fill the blank
struct Person {
    name: String,
    age: u8,
}
fn main() {
    println!("Success!");
} 

fn build_person(name: String, age: u8) -> Person {
    Person {
        age,
        __
    }
}
```

6. 🌟 You can create instance from other instance with *struct update syntax*
```rust,editable

// Fill the blank to make the code work
struct User {
    active: bool,
    username: String,
    email: String,
    sign_in_count: u64,
}
fn main() {
    let u1 = User {
        email: String::from("someone@example.com"),
        username: String::from("sunface"),
        active: true,
        sign_in_count: 1,
    };

    let u2 = set_email(u1);

    println!("Success!");
} 

fn set_email(u: User) -> User {
    User {
        email: String::from("contact@im.dev"),
        __
    }
}
```

### Print the structs
7. 🌟🌟 We can use `#[derive(Debug)]` to [make a struct printable](https://doc.rust-lang.org/book/ch05-02-example-structs.html?highlight=%23%5Bderive(Debug)%5D#adding-useful-functionality-with-derived-traits).

```rust,editable

// Fill the blanks to make the code work
#[__]
struct Rectangle {
    width: u32,
    height: u32,
}

fn main() {
    let scale = 2;
    let rect1 = Rectangle {
        width: dbg!(30 * scale), // Print debug info to stderr and assign the value of  `30 * scale` to `width`
        height: 50,
    };

    dbg!(&rect1); // Print debug info to stderr

    println!(__, rect1); // Print debug info to stdout
}
```

### Partial move
Within the destructuring of a single variable, both by-move and by-reference pattern bindings can be used at the same time. Doing this will result in a partial move of the variable, which means that parts of the variable will be moved while other parts stay. In such a case, the parent variable cannot be used afterwards as a whole, however the parts that are only referenced (and not moved) can still be used.

#### Example
```rust,editable

fn main() {
    #[derive(Debug)]
    struct Person {
        name: String,
        age: Box<u8>,
    }

    let person = Person {
        name: String::from("Alice"),
        age: Box::new(20),
    };

    // `name` is moved out of person, but `age` is referenced
    let Person { name, ref age } = person;

    println!("The person's age is {}", age);

    println!("The person's name is {}", name);

    // Error! borrow of partially moved value: `person` partial move occurs
    //println!("The person struct is {:?}", person);

    // `person` cannot be used but `person.age` can be used as it is not moved
    println!("The person's age from person struct is {}", person.age);
}
```


#### Exercises

8. 🌟🌟
```rust,editable

// Fix errors to make it work
#[derive(Debug)]
struct File {
    name: String,
    data: String,
}
fn main() {
    let f = File {
        name: String::from("readme.md"),
        data: "Rust By Practice".to_string()
    };

    let _name = f.name;

    // ONLY modify this line
    println!("{}, {}, {:?}",f.name, f.data, f);
} 
```

> You can find the solutions [here](https://github.com/sunface/rust-by-practice/blob/master/solutions/compound-types/struct.md)(under the solutions path), but only use it when you need it

================================================
FILE: en/src/compound-types/tuple.md
================================================
# Tuple
1. 🌟 Elements in a tuple can have different types. Tuple's type signature is `(T1, T2, ...)`, where `T1`, `T2` are the types of tuple's members.
```rust,editable

fn main() {
    let _t0: (u8,i16) = (0, -1);
    // Tuples can be tuple's members
    let _t1: (u8, (i16, u32)) = (0, (-1, 1));
    // Fill the blanks to make the code work
    let t: (u8, __, i64, __, __) = (1u8, 2u16, 3i64, "hello", String::from(", world"));

    println!("Success!");
}
```

2. 🌟 Members can be extracted from the tuple using indexing.
```rust,editable

// Make it work
fn main() {
    let t = ("i", "am", "sunface");
    assert_eq!(t.1, "sunface");

    println!("Success!");
}
```

3. 🌟 Long tuples  cannot be printed
```rust,editable

// Fix the error
fn main() {
    let too_long_tuple = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13);
    println!("too long tuple: {:?}", too_long_tuple);
}
```

4. 🌟 Destructuring tuple with pattern.
```rust,editable

fn main() {
    let tup = (1, 6.4, "hello");

    // Fill the blank to make the code work
    let __ = tup;

    assert_eq!(x, 1);
    assert_eq!(y, "hello");
    assert_eq!(z, 6.4);

    println!("Success!");
}
```

5. 🌟🌟 Destructure assignments.
```rust,editable
fn main() {
    let (x, y, z);

    // Fill the blank
    __ = (1, 2, 3);
    
    assert_eq!(x, 3);
    assert_eq!(y, 1);
    assert_eq!(z, 2);

    println!("Success!");
}
```

6. 🌟🌟 Tuples can be used as function arguments and return values
```rust,editable

fn main() {
    // Fill the blank, need a few computations here.
    let (x, y) = sum_multiply(__);

    assert_eq!(x, 5);
    assert_eq!(y, 6);

    println!("Success!");
}

fn sum_multiply(nums: (i32, i32)) -> (i32, i32) {
    (nums.0 + nums.1, nums.0 * nums.1)
}
```

> You can find the solutions [here](https://github.com/sunface/rust-by-practice/blob/master/solutions/compound-types/tuple.md)(under the solutions path), but only use it when you need it

================================================
FILE: en/src/crate-module/crate.md
================================================
# Package and Crate
A package is a project which you create with Cargo (in most cases), so it contains a `Cargo.toml` file in it.

1. 🌟 Create a package  with below layout:
```shell
.
├── Cargo.toml
└── src
    └── main.rs

1 directory, 2 files
```

```toml
# in Cargo.toml
[package]
name = "hello-package"
version = "0.1.0"
edition = "2021"
```

> Note! We will use this package across the whole chapter as a practice project.

2. 🌟 Create a package with below layout:
```shell
.
├── Cargo.toml
└── src
    └── lib.rs

1 directory, 2 files
```

```toml
# in Cargo.toml
[package]
name = "hello-package1"
version = "0.1.0"
edition = "2021"
```

> Note! This package could be safely removed due to the first one's existence.

3. 🌟 
```rust,editable
/* FILL in the blank with your ANSWER */

// Q: What's the difference between package number 1 and number 2?
// A: __
```


## Crate
A crate is a binary or library. The crate root is a source file that the Rust compiler starts from and makes up the root module of the crate.

In package `hello-package`, there is binary crate with the same name as the package : `hello-package`, and `src/main.rs` is the crate root of this binary crate.

Similar to `hello-package`, `hello-package1` also has a crate in it, however, this package doesn't contain a binary crate but a library crate, and `src/lib.rs` is the crate root.

4. 🌟
```rust,editable
/* FILL in the blank with your ANSWER */

// Q: What's the name of the library crate in package `hello-package1`?
// A: __
```


5. 🌟🌟 Add a library crate for `hello-package` and describe it's files tree below:
```shell,editable
# FILL in the blanks
.
├── Cargo.lock
├── Cargo.toml
├── src
│   ├── __
│   └── __
```

After this step, there should be two crates in package `hello-package`: **a binary crate and a library crate, both with the same name as the package**.

6. 🌟🌟🌟 A package can contain at most one library crate, but it can contain as many binary crates as you would like by placing files in `src/bin` directory: **each file will be a separate binary crate with the same name as the file**.

```shell,editable
# Create a package which contains 
# 1. three binary crates: `hello-package`, `main1` and `main2`
# 2. one library crate
# describe the directory tree below
.
├── Cargo.toml
├── Cargo.lock
├── src
│   ├── __
│   ├── __
│   └── __
│       └── __
│       └── __
├── tests # directory for integrated tests files
│   └── some_integration_tests.rs
├── benches # dir for benchmark files
│   └── simple_bench.rs
└── examples # dir for example files
    └── simple_example.rs
```

Yep, as you can see, the above package structure is very standard and is widely used in many Rust projects.


> You can find the solutions [here](https://github.com/sunface/rust-by-practice/blob/master/solutions/crate-module/crate.md) (under the solutions path), but only use it when you need it :)

================================================
FILE: en/src/crate-module/intro.md
================================================
# Crate and module
Learning resources: 
- English: [Rust Book Chapter 7](https://doc.rust-lang.org/book/ch07-00-managing-growing-projects-with-packages-crates-and-modules.html)
- 简体中文: [Rust语言圣经 - 包和模块](https://course.rs/basic/crate-module/intro.html)



================================================
FILE: en/src/crate-module/module.md
================================================
# Module
Modules let us organize the code within a crate into groups for readability and ease of reuse. Module also controls the privacy of items, which is whether an item can be seen by outside code( public ), or is just an internal implementation and not available for outside code( private ).


We have created a package named `hello-package` in previous chapter, and it looks like this:
```shell
.
├── Cargo.toml
├── src
│   ├── lib.rs
│   └── main.rs
```

Now it's time to create some modules in the library crate and use them in the binary crate, let's start.

1. 🌟🌟 Implement module `front_of_house` based on the module tree below:
```shell
library crate root
 └── front_of_house
     ├── hosting
     │   ├── add_to_waitlist
     │   └── seat_at_table
     └── serving
         ├── take_order
         ├── serve_order
         ├── take_payment
         └── complain
```

```rust,editable
// FILL in the blank
// in __.rs

mod front_of_house {
    // IMPLEMENT this module..
}
```


2. 🌟🌟 Let's call `add_to_waitlist` from a function `eat_at_restaurant` which is within the library crate root.

```rust,editable
// In lib.rs

// FILL in the blanks and FIX the errors
// You need to make something public with `pub` to provide accessibility for outside code `fn eat_at_restaurant()`
mod front_of_house {
    /* ...snip... */
}

pub fn eat_at_restaurant() {
    // Call add_to_waitlist with **absolute path**:
    __::add_to_waitlist();

    // Call with **relative path** 
     __::add_to_waitlist();
}
```

3. 🌟🌟 You can use `super` to import items within the parent module
```rust,editable
// In lib.rs

mod back_of_house {
    fn fix_incorrect_order() {
        cook_order();
        // FILL in the blank in three ways
        //1. using keyword `super`
        //2. using absolute path
        __::serve_order();
    }

    fn cook_order() {}
}
```


### Separating modules into different files
```rust,editable
// In lib.rs
pub mod front_of_house {
    pub mod hosting {
        pub fn add_to_waitlist() {}

        pub fn seat_at_table() -> String {
            String::from("sit down please")
        }
    }

    pub mod serving {
        pub fn take_order() {}

        pub fn serve_order() {}

        pub fn take_payment() {}

        // Maybe you don't want the guest hearing the your complaining about them
        // So just make it private
        fn complain() {} 
    }
}

pub fn eat_at_restaurant() -> String {
    front_of_house::hosting::add_to_waitlist();
    
    back_of_house::cook_order();

    String::from("yummy yummy!")
}

pub mod back_of_house {
    pub fn fix_incorrect_order() {
        cook_order();
        crate::front_of_house::serving::serve_order();
    }

    pub fn cook_order() {}
}
```

4. 🌟🌟🌟🌟 Please separate the modules and codes above into files resident in below dir tree :
```shell
.
├── Cargo.toml
├── src
│   ├── back_of_house.rs
│   ├── front_of_house
│   │   ├── hosting.rs
│   │   ├── mod.rs
│   │   └── serving.rs
│   ├── lib.rs
│   └── main.rs
```

```rust,editable
// In src/lib.rs

// IMPLEMENT...
```

```rust,editable
// In src/back_of_house.rs

// IMPLEMENT...
```


```rust,editable
// In src/front_of_house/mod.rs

// IMPLEMENT...
```

```rust,editable
// In src/front_of_house/hosting.rs

// IMPLEMENT...
```

```rust,editable
// In src/front_of_house/serving.rs

// IMPLEMENT...
```

### Accessing code in library crate from binary crate
**Please ensure you have completed the 4th exercise before making further progress.**

You should have below structures and the corresponding codes in them when reaching here: 
```shell
.
├── Cargo.toml
├── src
│   ├── back_of_house.rs
│   ├── front_of_house
│   │   ├── hosting.rs
│   │   ├── mod.rs
│   │   └── serving.rs
│   ├── lib.rs
│   └── main.rs
```

5. 🌟🌟🌟 Now we will call a few library functions from the binary crate.

```rust,editable
// In src/main.rs

// FILL in the blank and FIX the errors
fn main() {
    assert_eq!(__, "sit down please");
    assert_eq!(__,"yummy yummy!");
}
```

> You can find the solutions [here](https://github.com/sunface/rust-by-practice/blob/master/solutions/crate-module/module.md) (under the solutions path), but only use it when you need it :)


================================================
FILE: en/src/crate-module/use-pub.md
================================================
# Use and pub
1. 🌟 We can bring two types of the same name into the same scope with use, but you need `as` keyword.

```rust,editable
use std::fmt::Result;
use std::io::Result;

fn main() {}
```

2. 🌟🌟 If we are using multiple items defined in the same crate or module, then listing each item on its own line will take up too much vertical space.

```rust,editable

// FILL in the blank in two ways
// DON'T add new code line
use std::collections::__;

fn main() {
    let _c1:HashMap<&str, i32> = HashMap::new();
    let mut c2 = BTreeMap::new();
    c2.insert(1, "a");
    let _c3: HashSet<i32> = HashSet::new();
}
```

### Re-exporting names with `pub use`
3. 🌟🌟🌟 In our recently created package `hello-package`, add something to make the below code work
```rust,editable
fn main() {
    assert_eq!(hello_package::hosting::seat_at_table(), "sit down please");
     assert_eq!(hello_package::eat_at_restaurant(),"yummy yummy!");
}
```


### Pub(in Crate) 
Sometimes we want an item only be public to a certain crate. For this we can use the `pub(in Crate)` syntax.

#### Example
```rust,editable
pub mod a {
    pub const I: i32 = 3;

    fn semisecret(x: i32) -> i32 {
        use self::b::c::J;
        x + J
    }

    pub fn bar(z: i32) -> i32 {
        semisecret(I) * z
    }
    pub fn foo(y: i32) -> i32 {
        semisecret(I) + y
    }

    mod b {
        pub(in crate::a) mod c {
            pub(in crate::a) const J: i32 = 4;
        }
    }
}
```

### Full Code
The full code of `hello-package` is [here](https://github.com/sunface/rust-by-practice/tree/master/practices/hello-package).


> You can find the solutions [here](https://github.com/sunface/rust-by-practice/blob/master/solutions/crate-module/use-pub.md) (under the solutions path), but only use it when you need it :)

================================================
FILE: en/src/elegant-code-base.md
================================================
# Small projects with Elegant code base
Following questions come up weekly in online Rust discussions: 

- I just finished reading The Book, what should I do next ?
- What projects would you recommend to a Rust beginner?
- Looking for small projects with an elegant code base
- Codes that is easy to read and learn

The answers to these questions are always **Practice**: doing some exercises, and then reading some small and excellent Rust projects.

This is precisely the goal of this book, so, collecting relative resourses and representing in _Rust By Practice_ seems not a bad idea.

### 1. Ripgrep

Answers for above questions usually came with [`ripgrep`](https://github.com/BurntSushi/ripgrep), though I don't think it is a **small** project, but yes, go for it if you are not afraid to delve deep a bit.

### 2. Building a text editor
Tutorial [`https://www.flenker.blog/hecto/`](https://www.flenker.blog/hecto/) will lead you to build a text editor from scratch.

### 3. Ncspot
[Ncspot](https://github.com/hrkfdn/ncspot), a terminal Spotify client. Small, simple, well organized and async, it's good for learning.

### 4. Command Line Rust
[This project](https://github.com/kyclark/command-line-rust) is for the book `Command-Line Rust(O'Reily)`, it will show you how to write small CLIs (clones of `head`, `cat`, `ls`).

### 5. pngme book
[This book](https://jrdngr.github.io/pngme_book/) will guide you to make a command line program that lets you hide secret messages in PNG files.  The primary goal here is to get you writing code. The secondary goal is to get you reading documentation.

### 6. Writing an OS in Rust

[This blog series](https://os.phil-opp.com) creates a small operating system in the Rust programming language. Each post is a small tutorial and includes all needed code, so you can follow along if you like. The source code is also available in the corresponding [Github repository](https://github.com/phil-opp/blog_os).


### 7. CodeCrafters.io: Build your own Git, Docker, SQLite, or Redis

On [CodeCrafters](https://codecrafters.io/for/rust), you can recreate your favorite developer tools from scratch. It's a hands-on, minimally-guided approach to master Rust, while appreciating the internals and documentation of popular technology that we use every day.

### 8. mini-redis
[mini-redis](https://github.com/tokio-rs/mini-redis) is an incomplete Redis client and server implementation using tokio, it has decent code base and detail explanations, very suitable for learning Rust and asynchronous programming.

### 9. Writing Interpreters in Rust

[This online book](https://rust-hosted-langs.github.io/book/) will walk through the basics of interpreted language implementation in Rust with a focus on the challenges that are specific to using Rust.

---


**To be continued...**


================================================
FILE: en/src/errors.md
================================================
# Errors


================================================
FILE: en/src/fight-compiler/borrowing.md
================================================
# Borrowing

1. 🌟🌟
```rust,editable
// FIX the error without removing any code line
struct test {
    list: Vec<i32>,
    a: i32
}

impl test {
    pub fn new() -> Self {
        test { list:vec![1,2,3,4,5,6,7], a:0 }
    }

    pub fn run(&mut self) {
        for i in self.list.iter() {
            self.do_something(*i)
        }

    }

    pub fn do_something(&mut self, n: i32) {
        self.a = n;
    }
}

fn main() {}
```
> You can find the solutions [here](https://github.com/sunface/rust-by-practice/blob/master/solutions/fight-compiler/borrowing.md)(under the solutions path), but only use it when you need it :)


================================================
FILE: en/src/fight-compiler/intro.md
================================================
# Fighting with Compiler
Fighting with compiler is very common in our daily coding, especially for those unfamiliar with Rust.

This chapter will provide some exercises to help us avoid such cases to lower the steep learning curve.

================================================
FILE: en/src/flow-control.md
================================================
# Flow control

### If/else
1. 🌟 
```rust,editable

// Fill in the blanks
fn main() {
    let n = 5;

    if n < 0 {
        println!("{} is negative", n);
    } __ n > 0 {
        println!("{} is positive", n);
    } __ {
        println!("{} is zero", n);
    }
} 
```

2. 🌟🌟 `If/else` expression can be used in assignments.
```rust,editable

// Fix the errors
fn main() {
    let n = 5;

    let big_n =
        if n < 10 && n > -10 {
            println!(", and is a small number, increase ten-fold");

            10 * n
        } else {
            println!(", and is a big number, halve the number");

            n / 2.0 ;
        }

    println!("{} -> {}", n, big_n);
} 
```

### For
3. 🌟 The `for in` construct can be used to iterate through an Iterator, e.g a range `a..b`.

```rust,editable

fn main() {
    for n in 1..=100 { // modify this line to make the code work
        if n == 100 {
            panic!("NEVER LET THIS RUN")
        }
    }

    println!("Success!");
} 
```


4. 🌟🌟 
```rust,editable

// Fix the errors without adding or removing lines
fn main() {
    let names = [String::from("liming"),String::from("hanmeimei")];
    for name in names {
        // Do something with name...
    }

    println!("{:?}", names);

    let numbers = [1, 2, 3];
    // The elements in numbers are Copy,so there is no move here
    for n in numbers {
        // Do something with n...
    }
    
    println!("{:?}", numbers);
} 
```

5. 🌟
```rust,editable
fn main() {
    let a = [4, 3, 2, 1];

    // Iterate the indexing and value in 'a'
    for (i,v) in a.__ {
        println!("The {}th element is {}",i+1,v);
    }
}
```

### While
6. 🌟🌟 The `while` keyword can be used to run a loop when a condition is true.

```rust,editable

// Fill in the blanks to make the last println! work !
fn main() {
    // A counter variable
    let mut n = 1;

    // Loop while the condition is true
    while n __ 10 {
        if n % 15 == 0 {
            println!("fizzbuzz");
        } else if n % 3 == 0 {
            println!("fizz");
        } else if n % 5 == 0 {
            println!("buzz");
        } else {
            println!("{}", n);
        }


        __;
    }

    println!("n reached {}, so loop is over",n);
}
```

### Continue and break
7. 🌟 Use `break` to break the loop.
```rust,editable

// Fill in the blank
fn main() {
    let mut n = 0;
    for i in 0..=100 {
       if n == 66 {
           __
       }
       n += 1;
    }

    assert_eq!(n, 66);

    println!("Success!");
}
```

8. 🌟🌟 `continue` will skip over the remaining code in current iteration and go to the next iteration.
```rust,editable

// Fill in the blanks
fn main() {
    let mut n = 0;
    for i in 0..=100 {
       if n != 66 {
           n+=1;
           __;
       }
       
       __
    }

    assert_eq!(n, 66);

    println!("Success!");
}
```

### Loop 

9. 🌟🌟 Loop is usually used together with `break` or `continue`.

```rust,editable

// Fill in the blanks
fn main() {
    let mut count = 0u32;

    println!("Let's count until infinity!");

    // Infinite loop
    loop {
        count += 1;

        if count == 3 {
            println!("three");

            // Skip the rest of this iteration
            __;
        }

        println!("{}", count);

        if count == 5 {
            println!("OK, that's enough");

            __;
        }
    }

    assert_eq!(count, 5);

    println!("Success!");
}
```

10. 🌟🌟 Loop is an expression, so we can use it with `break` to return a value
```rust,editable

// Fill in the blank
fn main() {
    let mut counter = 0;

    let result = loop {
        counter += 1;

        if counter == 10 {
            __;
        }
    };

    assert_eq!(result, 20);

    println!("Success!");
}
```

11. 🌟🌟🌟 It's possible to break or continue outer loops when dealing with nested loops. In these cases, the loops must be annotated with some 'label, and the label must be passed to the break/continue statement.

```rust,editable

// Fill in the blank
fn main() {
    let mut count = 0;
    'outer: loop {
        'inner1: loop {
            if count >= 20 {
                // This would break only the inner1 loop
                break 'inner1; // `break` is also works.
            }
            count += 2;
        }

        count += 5;

        'inner2: loop {
            if count >= 30 {
                // This breaks the outer loop
                break 'outer;
            }

            // This will continue the outer loop
            continue 'outer;
        }
    }

    assert!(count == __);

    println!("Success!");
}
```

> You can find the solutions [here](https://github.com/sunface/rust-by-practice)(under the solutions path), but only use it when you need it

================================================
FILE: en/src/formatted-output/debug-display.md
================================================
# Debug and Display
All types which want to be printable must implement the `std::fmt` formatting trait: `std::fmt::Debug` or `std::fmt::Display`. 

Automatic implementations are only provided for types such as in the `std` library. All others have to be manually implemented.

## Debug
The implementation of `Debug` is very straightforward: All types can `derive` the `std::fmt::Debug` implementation. This is not true for `std::fmt::Display` which must be manually implemented.

`{:?}` must be used to print out the type which has implemented the `Debug` trait.

```rust
// This structure cannot be printed either with `fmt::Display` or
// with `fmt::Debug`.
struct UnPrintable(i32);

// To make this struct printable with `fmt::Debug`, we can derive the automatic implementations provided by Rust
#[derive(Debug)]
struct DebugPrintable(i32);
```

1. 🌟
```rust,editable

/* Fill in the blanks and Fix the errors */
struct Structure(i32);

fn main() {
    // Types in std and Rust have implemented the fmt::Debug trait
    println!("__ months in a year.", 12);

    println!("Now __ will print!", Structure(3));
}
```

2. 🌟🌟 So `fmt::Debug` definitely makes one type printable, but sacrifices some elegance. Maybe we can get more elegant by replacing `{:?}` with something else( but not `{}` !) 
```rust,editable
#[derive(Debug)]
struct Person {
    name: String,
    age: u8
}

fn main() {
    let person = Person { name:  "Sunface".to_string(), age: 18 };

    /* Make it output: 
    Person {
        name: "Sunface",
        age: 18,
    }
    */
    println!("{:?}", person);
}
```

3. 🌟🌟 We can also manually implement `Debug` trait for our types
```rust,editable

#[derive(Debug)]
struct Structure(i32);

#[derive(Debug)]
struct Deep(Structure);


fn main() {    
    // The problem with `derive` is there is no control over how
    // the results look. What if I want this to just show a `7`?

    /* Make it print: Now 7 will print! */
    println!("Now {:?} will print!", Deep(Structure(7)));
}
```

## Display
Yeah, `Debug` is simple and easy to use. But sometimes we want to customize the output appearance of our type. This is where `Display` really shines.

Unlike `Debug`, there is no way to derive the implementation of the `Display` trait, we have to manually implement it.

Another thing to note: the placeholder for `Display` is `{}` not `{:?}`.

4. 🌟🌟
```rust,editable

/* Make it work*/
use std::fmt;

struct Point2D {
    x: f64,
    y: f64,
}

impl fmt::Display for Point2D {
    /* Implement.. */
}

impl fmt::Debug for Point2D {
    /* Implement.. */
}

fn main() {
    let point = Point2D { x: 3.3, y: 7.2 };
    assert_eq!(format!("{}",point), "Display: 3.3 + 7.2i");
    assert_eq!(format!("{:?}",point), "Debug: Complex { real: 3.3, imag: 7.2 }");
    
    println!("Success!");
}
```


### `?` operator

Implementing `fmt::Display` for a structure whose elements must be handled separately is tricky. The problem is each `write!` generates a `fmt::Result` which must be handled in the same place.

Fortunately, Rust provides the `?` operator to help us eliminate some unnecessary codes for dealing with `fmt::Result`.

5. 🌟🌟
```rust,editable

/* Make it work */
use std::fmt; 

struct List(Vec<i32>);

impl fmt::Display for List {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        // Extract the value using tuple indexing,
        // and create a reference to `vec`.
        let vec = &self.0;

        write!(f, "[")?;

        // Iterate over `v` in `vec` while enumerating the iteration
        // count in `count`.
        for (count, v) in vec.iter().enumerate() {
            // For every element except the first, add a comma.
            // Use the ? operator to return on errors.
            if count != 0 { write!(f, ", ")?; }
            write!(f, "{}", v)?;
        }

        // Close the opened bracket and return a fmt::Result value.
        write!(f, "]")
    }
}

fn main() {
    let v = List(vec![1, 2, 3]);
    assert_eq!(format!("{}",v), "[0: 1, 1: 2, 2: 3]");
    println!("Success!");
}
```


> You can find the solutions [here](https://github.com/sunface/rust-by-practice/blob/master/solutions/formatted-output/debug-display.md)(under the solutions path), but only use it when you need it :)


================================================
FILE: en/src/formatted-output/formatting.md
================================================
# Formatting

## Positional arguments

1.🌟🌟
```rust,editable
/* Fill in the blanks */
fn main() {
    println!("{0}, this is {1}. {1}, this is {0}", "Alice", "Bob"); // => Alice, this is Bob. Bob, this is Alice
    assert_eq!(format!("{1}{0}", 1, 2), __);
    assert_eq!(format!(__, 1, 2), "2112");
    println!("Success!");
}
```

## Named arguments

2.🌟🌟
```rust,editable
fn main() {
    println!("{argument}", argument = "test"); // => "test"

    /* Fill in the blanks */
    assert_eq!(format!("{name}{}", 1, __), "21");
    assert_eq!(format!(__,a = "a", b = 'b', c = 3 ), "a 3 b");
    
    /* Fix the error */
    // Named argument must be placed after other arguments
    println!("{abc} {1}", abc = "def", 2);

    println!("Success!");
}
```

## Padding with string

3.🌟🌟 By default, you can pad string with spaces
```rust,editable
fn main() {
    // The following two are padding with 5 spaces
    println!("Hello {:5}!", "x"); // =>  "Hello x    !"  
    println!("Hello {:1$}!", "x", 5); // =>  "Hello x    !"

    /* Fill in the blanks */
    assert_eq!(format!("Hello __!", 5, "x"), "Hello x    !");
    assert_eq!(format!("Hello __!", "x", width = 5), "Hello x    !");

    println!("Success!");
}
```

4.🌟🌟🌟 Left align, right align, pad with specified characters.
```rust,editable
fn main() {
    // Left align
    println!("Hello {:<5}!", "x"); // => Hello x    !
    // Right align
    assert_eq!(format!("Hello __!", "x"), "Hello     x!");
    // Center align
    assert_eq!(format!("Hello __!", "x"), "Hello   x  !");

    // Left align, pad with '&'
    assert_eq!(format!("Hello {:&<5}!", "x"), __);

    println!("Success!");
}
```

5.🌟🌟 You can pad numbers with extra zeros.
```rust,editable
fn main() {
    println!("Hello {:5}!", 5); // => Hello     5!
    println!("Hello {:+}!", 5); // =>  Hello +5!
    println!("Hello {:05}!", 5); // => Hello 00005!
    println!("Hello {:05}!", -5); // => Hello -0005!

    /* Fill in the blank */
    assert!(format!("{number:0>width$}", number=1, width=6) == __);
    
    println!("Success!")
;}
```

## Precision
6.🌟🌟 Floating point precision
```rust,editable

/* Fill in the blanks */
fn main() {
    let v = 3.1415926;

    println!("{:.1$}", v, 4); // same as {:.4} => 3.1416 

    assert_eq!(format!("__", v), "3.14");
    assert_eq!(format!("__", v), "+3.14");
    assert_eq!(format!("__", v), "3");

    println!("Success!");
}
```

7.🌟🌟🌟 String length
```rust,editable
fn main() {
    let s = "Hello, world!";

    println!("{0:.5}", s); // => Hello

    assert_eq!(format!("Hello __!", 3, "abcdefg"), "Hello abc!");

    println!("Success!");
}
```   

## Binary, octal, hex

- format!("{}", foo) -> "3735928559"
- format!("0x{:X}", foo) -> "0xDEADBEEF"
- format!("0o{:o}", foo) -> "0o33653337357"
  
8.🌟🌟
```rust,editable
fn main() {
    assert_eq!(format!("__", 27), "0b11011");
    assert_eq!(format!("__", 27), "0o33");
    assert_eq!(format!("__", 27), "0x1b");
    assert_eq!(format!("__", 27), "0x1B");

    println!("{:x}!", 27); // Hex with no prefix => 1b

    println!("{:#010b}", 27); // Pad binary with 0, width = 10,  => 0b00011011

    println!("Success!");
}
```

## Capture the environment
9.🌟🌟🌟
```rust,editable
fn get_person() -> String {
    String::from("sunface")
}

fn get_format() -> (usize, usize) {
    (4, 1)
}


fn main() {
    let person = get_person();
    println!("Hello, {person}!");

    let (width, precision) = get_format();
    let scores = [("sunface", 99.12), ("jack", 60.34)];
    /* Make it print:
    sunface: 99.1
    jack: 60.3
    */
    for (name, score) in scores {
        println!("{name}: __");
    }
}
```


## Others

**Example**
```rust,editable
fn main() {
    // Exponent
    println!("{:2e}", 1000000000); // => 1e9
    println!("{:2E}", 1000000000); // => 1E9

    // Pointer address
    let v= vec![1, 2, 3];
    println!("{:p}", v.as_ptr()); // => 0x600002324050

    // Escape
    println!("Hello {{}}"); // => Hello {}
}
```

> You can find the solutions [here](https://github.com/sunface/rust-by-practice/blob/master/solutions/formatted-output/formatting.md)(under the solutions path), but only use it when you need it :)


================================================
FILE: en/src/formatted-output/intro.md
================================================
# Formatted output

```rust,editable,ignore,mdbook-runnable
fn main() {
    // In general, the `{}` will be automatically replaced with any
    // arguments. These will be stringified.
    println!("{} days", 31);

    // Without a suffix, 31 becomes an i32. You can change what type 31 is
    // by providing a suffix. The number 31i64 for example has the type i64.

    // There are various optional patterns this works with. Positional
    // arguments can be used.
    println!("{0}, this is {1}. {1}, this is {0}", "Alice", "Bob");

    // As can named arguments.
    println!("{subject} {verb} {object}",
             object="the lazy dog",
             subject="the quick brown fox",
             verb="jumps over");

    // Special formatting can be specified after a `:`.
    println!("{} of {:b} people know binary, the other half doesn't", 1, 2);

    // You can right-align text with a specified width. This will output
    // "     1". 5 white spaces and a "1".
    println!("{number:>width$}", number=1, width=6);

    // You can pad numbers with extra zeroes. This will output "000001".
    println!("{number:0>width$}", number=1, width=6);

    // Rust even checks to make sure the correct number of arguments are
    // used.
    println!("My name is {0}, {1} {0}", "Bond");
    // FIXME ^ Add the missing argument: "James"

    // Create a structure named `Structure` which contains an `i32`.
    #[allow(dead_code)]
    struct Structure(i32);

    // However, custom types such as this structure require more complicated
    // handling. This will not work.
    println!("This struct `{}` won't print...", Structure(3));
    // FIXME ^ Comment out this line.

    // For Rust 1.58 and above, you can directly capture the argument from
    // surrounding variable. Just like the above, this will output
    // "     1". 5 white spaces and a "1".
    let number: f64 = 1.0;
    let width: usize = 6;
    println!("{number:>width$}");
}
```

[`std::fmt`][fmt] contains many [`traits`][traits] which govern the display
of text. The base form of two important ones are listed below:

* `fmt::Debug`: Uses the `{:?}` marker. Format text for debugging purposes.
* `fmt::Display`: Uses the `{}` marker. Format text in a more elegant, user
friendly fashion.

Here, we used `fmt::Display` because the std library provides implementations
for these types. To print text for custom types, more steps are required.

Implementing the `fmt::Display` trait automatically implements the
[`ToString`] trait which allows us to [convert] the type to [`String`][string].


================================================
FILE: en/src/formatted-output/println.md
================================================
# println! and format!
Printing is handled by a series of [`macros`][macros] defined in [`std::fmt`][fmt]
Some of which include:

* `format!`: write formatted text to [`String`][string]
* `print!`: same as `format!` but the text is printed to the console (io::stdout).
* `println!`: same as `print!` but a newline is appended.
* `eprint!`: same as `format!` but the text is printed to the standard error (io::stderr).
* `eprintln!`: same as `eprint!`but a newline is appended.

All parse text in the same fashion. As a plus, Rust checks format correctness at compile time.

## `format!`
1.🌟
```rust,editable

fn main() {
    let s1 = "hello";
    /* Fill in the blank */
    let s = format!(__);
    assert_eq!(s, "hello, world!");
}
```

## `print!`, `println!`
2.🌟
```rust,editable

fn main() {
   /* Fill in the blanks to make it print:
   Hello world, I am 
   Sunface!
   */
   __("hello world, ");
   __("I am");
   __("Sunface!");
}
```

> You can find the solutions [here](https://github.com/sunface/rust-by-practice/blob/master/solutions/formatted-output/println.md)(under the solutions path), but only use it when you need it :)


================================================
FILE: en/src/functional-programing/closure.md
================================================
# Closure
Closures can capture the enclosing environments. For example we can capture the `x` variable :
```rust
fn main() {
    let x = 1;
    let closure = |val| val + x;
    assert_eq!(closure(2), 3);
}
```

From the syntax, we can see that closures are very convenient for on the fly usage. Unlike functions, both the input and return types of a closure can be inferred by the compiler.

```rust
fn main() {
    // Increment via closures and functions.
    fn function(i: i32) -> i32 { i + 1 }

    // Closures are anonymous, here we are binding them to references
    // 
    // These nameless functions are assigned to appropriately named variables.
    let closure_annotated = |i: i32| -> i32 { i + 1 };
    let closure_inferred  = |i     |          i + 1  ;

    let i = 1;
    // Call the function and closures.
    println!("function: {}", function(i));
    println!("closure_annotated: {}", closure_annotated(i));
    println!("closure_inferred: {}", closure_inferred(i));

    // A closure taking no arguments which returns an `i32`.
    // The return type is inferred.
    let one = || 1;
    println!("closure returning one: {}", one());

}
```

## Capturing
Closures can capture variables by borrowing or moving. But they prefer to capture by borrowing and only go lower when required:
- By reference: `&T`
- By mutable reference: `&mut T`
- By value: `T`


1. 🌟

```rust,editable
/* Make it work with least amount of changes*/
fn main() {
    let color = String::from("green");

    let print = move || println!("`color`: {}", color);

    print();
    print();

    // `color` can be borrowed immutably again, because the closure only holds
    // an immutable reference to `color`. 
    let _reborrow = &color;

    println!("{}",color);
}
```


2. 🌟🌟

```rust,editable
/* Make it work 
- Dont use `_reborrow` and `_count_reborrowed`
- Dont modify `assert_eq`
*/
fn main() {
    let mut count = 0;

    let mut inc = || {
        count += 1;
        println!("`count`: {}", count);
    };

    inc();


    let _reborrow = &count; 

    inc();

    // The closure no longer needs to borrow `&mut count`. Therefore, it is
    // possible to reborrow without an error
    let _count_reborrowed = &mut count; 

    assert_eq!(count, 0);
}
```


3. 🌟🌟

```rust,editable
/* Make it work in two ways, none of them is to remove `take(movable)` away from the code
*/
fn main() {
     let movable = Box::new(3);

     let consume = || {
         println!("`movable`: {:?}", movable);
         take(movable);
     };

     consume();
     consume();
}

fn take<T>(_v: T) {}
```

For comparison, the following code has no error: 
```rust
fn main() {
     let movable = Box::new(3);

     let consume = move || {
         println!("`movable`: {:?}", movable);
     };

     consume();
     consume();
}
```

## Type inferred
The following four closures has no difference in input and return  types.

```rust
fn  add_one_v1   (x: u32) -> u32 { x + 1 }
let add_one_v2 = |x: u32| -> u32 { x + 1 };
let add_one_v3 = |x|             { x + 1 };
let add_one_v4 = |x|               x + 1  ;
```


4. 🌟

```rust,editable
fn main() {
    let example_closure = |x| x;

    let s = example_closure(String::from("hello"));

    /* Make it work, only change the following line */
    let n = example_closure(5);
}
```

## Fn, FnMut, FnOnce
When taking a closure as an input parameter, the closure's complete type must be annotated using one of the following traits:

- Fn: the closure uses the captured value by reference (&T)
- FnMut: the closure uses the captured value by mutable reference (&mut T)
- FnOnce: the closure uses the captured value by value (T)


5. 🌟🌟

```rust,editable
/* Make it work by changing the trait bound, in two ways*/
fn fn_once<F>(func: F)
where
    F: FnOnce(usize) -> bool,
{
    println!("{}", func(3));
    println!("{}", func(4));
}

fn main() {
    let x = vec![1, 2, 3];
    fn_once(|z|{z == x.len()})
}
```

6. 🌟🌟
```rust,editable
fn main() {
    let mut s = String::new();

    let update_string = |str| s.push_str(str);

    exec(update_string);

    println!("{:?}",s);
}

/* Fill in the blank */
fn exec<'a, F: __>(mut f: F)  {
    f("hello")
}
```
 
#### Which trait does the compiler prefer to use?
- Fn: the closure uses the captured value by reference (&T)
- FnMut: the closure uses the captured value by mutable reference (&mut T)
- FnOnce: the closure uses the captured value by value (T)

On a variable-by-variable basis, the compiler will capture variables in the least restrictive manner possible.

For instance, consider a parameter annotated as FnOnce. This specifies that the closure may capture by `&T`, `&mut T`, or `T`, but the compiler will ultimately choose based on how the captured variables are used in the closure.
Which trait to use is determined by what the closure does with captured value. 

This is because if a move is possible, then any type of borrow should also be possible. Note that the reverse is not true. If the parameter is annotated as `Fn`, then capturing variables by `&mut T` or `T` are not allowed.


7. 🌟🌟

```rust,editable
/* Fill in the blank */

// A function which takes a closure as an argument and calls it.
// <F> denotes that F is a "Generic type parameter"
fn apply<F>(f: F) where
    // The closure takes no input and returns nothing.
    F: __ {

    f();
}

// A function which takes a closure and returns an `i32`.
fn apply_to_3<F>(f: F) -> i32 where
    // The closure takes an `i32` and returns an `i32`.
    F: Fn(i32) -> i32 {

    f(3)
}

fn main() {
    use std::mem;

    let greeting = "hello";
    // A non-copy type.
    // `to_owned` creates owned data from borrowed one
    let mut farewell = "goodbye".to_owned();

    // Capture 2 variables: `greeting` by reference and
    // `farewell` by value.
    let diary = || {
        // `greeting` is by reference: requires `Fn`.
        println!("I said {}.", greeting);

        // Mutation forces `farewell` to be captured by
        // mutable reference. Now requires `FnMut`.
        farewell.push_str("!!!");
        println!("Then I screamed {}.", farewell);
        println!("Now I can sleep. zzzzz");

        // Manually calling drop forces `farewell` to
        // be captured by value. Now requires `FnOnce`.
        mem::drop(farewell);
    };

    // Call the function which applies the closure.
    apply(diary);

    // `double` satisfies `apply_to_3`'s trait bound
    let double = |x| 2 * x;

    println!("3 doubled: {}", apply_to_3(double));
}
```

Move closures may still implement `Fn` or `FnMut`, even though they capture variables by move. This is because the traits implemented by a closure type are determined by what the closure does with captured values, not how it captures them. The `move` keyword only specifies the latter.

```rust
fn main() {
    let s = String::new();

    let update_string = move || println!("{}",s);

    exec(update_string);
}

fn exec<F: FnOnce()>(f: F)  {
    f()
}
```

The following code also has no error:
```rust
fn main() {
    let s = String::new();

    let update_string = move || println!("{}",s);

    exec(update_string);
}

fn exec<F: Fn()>(f: F)  {
    f()
}
```


8. 🌟🌟

```rust,editable
/* Fill in the blank */
fn main() {
    let mut s = String::new();

    let update_string = |str| -> String {s.push_str(str); s };

    exec(update_string);
}

fn exec<'a, F: __>(mut f: F) {
    f("hello");
}
```


## Input functions
Since closure can be used as arguments, you might wonder can we use functions as arguments too? And indeed we can.


9. 🌟🌟

```rust,editable

/* Implement `call_me` to make it work */
fn call_me {
    f();
}

fn function() {
    println!("I'm a function!");
}

fn main() {
    let closure = || println!("I'm a closure!");

    call_me(closure);
    call_me(function);
}
```

## Closure as return types
Returning a closure is much harder than you may have thought of.


10. 🌟🌟

```rust,editable
/* Fill in the blank using two approaches,
 and fix the error */
fn create_fn() -> __ {
    let num = 5;

    // How does the following closure capture the environment variable `num`
    // &T, &mut T, T ?
    |x| x + num
}


fn main() {
    let fn_plain = create_fn();
    fn_plain(1);
}
```


11. 🌟🌟

```rust,editable
/* Fill in the blank and fix the error*/
fn factory(x:i32) -> __ {

    let num = 5;

    if x > 1{
        move |x| x + num
    } else {
        move |x| x + num
    }
}
```


## Closure in structs

**Example**
```rust
struct Cacher<T,E>
where
    T: Fn(E) -> E,
    E: Copy
{
    query: T,
    value: Option<E>,
}

impl<T,E> Cacher<T,E>
where
    T: Fn(E) -> E,
    E: Copy
{
    fn new(query: T) -> Cacher<T,E> {
        Cacher {
            query,
            value: None,
        }
    }

    fn value(&mut self, arg: E) -> E {
        match self.value {
            Some(v) => v,
            None => {
                let v = (self.query)(arg);
                self.value = Some(v);
                v
            }
        }
    }
}
fn main() {
  
}

#[test]
fn call_with_different_values() {
    let mut c = Cacher::new(|a| a);

    let v1 = c.value(1);
    let v2 = c.value(2);

    assert_eq!(v2, 1);
}
```
> You can find the solutions [here](https://github.com/sunface/rust-by-practice/blob/master/solutions/functional-programing/closure.md)(under the solutions path), but only use it when you need it :)


================================================
FILE: en/src/functional-programing/intro.md
================================================
# Functional programing
Learning resources: 
- English: [Rust Book 13](https://doc.rust-lang.org/book/ch13-00-functional-features.html)
- 简体中文: [Rust语言圣经 - 函数式编程:闭包和迭代器](https://course.rs/advance/functional-programing/intro.html)



================================================
FILE: en/src/functional-programing/iterator.md
================================================
# Iterator
The iterator pattern allows us to perform some tasks on a sequence of items in turn. An iterator is responsible for the logic of iterating over each item and determining when the sequence has finished.

## for and iterator
```rust
fn main() {
    let v = vec![1, 2, 3];
    for x in v {
        println!("{}",x)
    }
}
```

In the code above, You may consider `for` as a simple loop, but actually it is iterating over a iterator. 

By default  `for` will apply the `into_iter` to the collection, and change it into a iterator. As a result, the following code is equivalent to previous one:
```rust
fn main() {
    let v = vec![1, 2, 3];
    for x in v.into_iter() {
        println!("{}",x)
    }
}
```


1. 🌟

```rust,editable
/* Refactoring the following code using iterators */
fn main() {
    let arr = [0; 10];
    for i in 0..arr.len() {
        println!("{}",arr[i]);
    }
}
```

2. 🌟 One of the easiest ways to create an iterator is to use the range notion: `a..b`.
```rust,editable
/* Fill in the blank */
fn main() {
    let mut v = Vec::new();
    for n in __ {
       v.push(n);
    }

    assert_eq!(v.len(), 100);
}
```

## next method
All iterators implement a trait named `Iterator` that is defined in the standard library:
```rust
pub trait Iterator {
    type Item;

    fn next(&mut self) -> Option<Self::Item>;

    // Methods with default implementations elided
}
```

And we can call the `next` method on iterators directly.


3. 🌟🌟

```rust,editable
/* Fill the blanks and fix the errors.
Using two ways if possible */
fn main() {
    let v1 = vec![1, 2];

    assert_eq!(v1.next(), __);
    assert_eq!(v1.next(), __);
    assert_eq!(v1.next(), __);
}
```

## into_iter, iter and iter_mut
In the previous section, we have mentioned that `for` will apply the `into_iter` to the collection, and change it into a iterator. However, this is not the only way to convert collections into iterators.

`into_iter`, `iter`, `iter_mut`, all of them can convert a collection into iterator, but in different ways.

- `into_iter` consumes the collection, once the collection has been consumed, it is no longer available for reuse, because its ownership has been moved within the loop.
- `iter`, this borrows each element of the collection through each iteration, thus leaving the collection untouched and available for reuse after the loop
- `iter_mut`, this mutably borrows each element of the collection, allowing for the collection to be modified in place.


4. 🌟

```rust,editable
/* Make it work */
fn main() {
    let arr = vec![0; 10];
    for i in arr {
        println!("{}", i);
    }

    println!("{:?}",arr);
}
```


5. 🌟

```rust,editable
/* Fill in the blank */
fn main() {
    let mut names = vec!["Bob", "Frank", "Ferris"];

    for name in names.__{
        *name = match name {
            &mut "Ferris" => "There is a rustacean among us!",
            _ => "Hello",
        }
    }

    println!("names: {:?}", names);
}
```


6. 🌟🌟

```rust,editable
/* Fill in the blank */
fn main() {
    let mut values = vec![1, 2, 3];
    let mut values_iter = values.__;

    if let Some(v) = values_iter.__{
        __
    }

    assert_eq!(values, vec![0, 2, 3]);
}
```


## Creating our own iterator
We can not only create iterators from collection's types, but also can create iterators by implementing the `Iterator` trait on our own types.

**Example**
```rust
struct Counter {
    count: u32,
}

impl Counter {
    fn new() -> Counter {
        Counter { count: 0 }
    }
}

impl Iterator for Counter {
    type Item = u32;

    fn next(&mut self) -> Option<Self::Item> {
        if self.count < 5 {
            self.count += 1;
            Some(self.count)
        } else {
            None
        }
    }
}

fn main() {
    let mut counter = Counter::new();

    assert_eq!(counter.next(), Some(1));
    assert_eq!(counter.next(), Some(2));
    assert_eq!(counter.next(), Some(3));
    assert_eq!(counter.next(), Some(4));
    assert_eq!(counter.next(), Some(5));
    assert_eq!(counter.next(), None);
}
```


7. 🌟🌟🌟

```rust,editable
struct Fibonacci {
    curr: u32,
    next: u32,
}

// Implement `Iterator` for `Fibonacci`.
// The `Iterator` trait only requires a method to be defined for the `next` element.
impl Iterator for Fibonacci {
    // We can refer to this type using Self::Item
    type Item = u32;
    
    /* Implement next method */
    fn next(&mut self)
}

// Returns a Fibonacci sequence generator
fn fibonacci() -> Fibonacci {
    Fibonacci { curr: 0, next: 1 }
}

fn main() {
    let mut fib = fibonacci();
    assert_eq!(fib.next(), Some(1));
    assert_eq!(fib.next(), Some(1));
    assert_eq!(fib.next(), Some(2));
    assert_eq!(fib.next(), Some(3));
    assert_eq!(fib.next(), Some(5));
}
```

## Methods that Consume the Iterator
The `Iterator` trait has a number of methods with default implementations provided by the standard library.


### Consuming adaptors
Some of these methods call the method `next`to use up the iterator, so they are called *consuming adaptors*.


8. 🌟🌟

```rust,editable

/* Fill in the blank and fix the errors */
fn main() {
    let v1 = vec![1, 2, 3];

    let v1_iter = v1.iter();

    // The sum method will take the ownership of the iterator and iterates through the items by repeatedly calling next method
    let total = v1_iter.sum();

    assert_eq!(total, __);

    println!("{:?}, {:?}",v1, v1_iter);
}
```


#### Collect
Other than converting a collection into an iterator, we can also `collect` the result values into a collection, `collect` will consume the iterator.


9. 🌟🌟

```rust,editable
/* Make it work */
use std::collections::HashMap;
fn main() {
    let names = [("sunface",18), ("sunfei",18)];
    let folks: HashMap<_, _> = names.into_iter().collect();

    println!("{:?}",folks);

    let v1: Vec<i32> = vec![1, 2, 3];

    let v2 = v1.iter().collect();

    assert_eq!(v2, vec![1, 2, 3]);
}
```


###  Iterator adaptors
Methods allowing you to change one iterator into another iterator are known as *iterator adaptors*. You can chain multiple iterator adaptors to perform complex actions in a readable way.

But because **all iterators are lazy**, you have to call one of the consuming adapters to get results from calls to iterator adapters.


10. 🌟🌟

```rust,editable
/* Fill in the blanks */
fn main() {
    let v1: Vec<i32> = vec![1, 2, 3];

    let v2: Vec<_> = v1.iter().__.__;

    assert_eq!(v2, vec![2, 3, 4]);
}
```


11. 🌟🌟

```rust,editable
/* Fill in the blanks */
use std::collections::HashMap;
fn main() {
    let names = ["sunface", "sunfei"];
    let ages = [18, 18];
    let folks: HashMap<_, _> = names.into_iter().__.collect();

    println!("{:?}",folks);
}
```


#### Using closures in iterator adaptors


12. 🌟🌟 

```rust,editable
/* Fill in the blanks */
#[derive(PartialEq, Debug)]
struct Shoe {
    size: u32,
    style: String,
}

fn shoes_in_size(shoes: Vec<Shoe>, shoe_size: u32) -> Vec<Shoe> {
    shoes.into_iter().__.collect()
}

fn main() {
    let shoes = vec![
        Shoe {
            size: 10,
            style: String::from("sneaker"),
        },
        Shoe {
            size: 13,
            style: String::from("sandal"),
        },
        Shoe {
            size: 10,
            style: String::from("boot"),
        },
    ];

    let in_my_size = shoes_in_size(shoes, 10);

    assert_eq!(
        in_my_size,
        vec![
            Shoe {
                size: 10,
                style: String::from("sneaker")
            },
            Shoe {
                size: 10,
                style: String::from("boot")
            },
        ]
    );
}
```

> You can find the solutions [here](https://github.com/sunface/rust-by-practice/blob/master/solutions/functional-programing/iterator.md)(under the solutions path), but only use it when you need it :)


================================================
FILE: en/src/generics-traits/advanced-traits.md
================================================
# Advance Traits

## Associated types
The use of "Associated types" improves the overall readability of code by moving inner types locally into a trait as output types. For example :
```rust
pub trait CacheableItem: Clone + Default + fmt::Debug + Decodable + Encodable {
  type Address: AsRef<[u8]> + Clone + fmt::Debug + Eq + Hash;
  fn is_null(&self) -> bool;
}
```

Using of `Address` is much more clearer and convenient than `AsRef<[u8]> + Clone + fmt::Debug + Eq + Hash`.

1. 🌟🌟🌟
```rust,editable

struct Container(i32, i32);

// USING associated types to re-implement trait Contains.
// trait Contains {
//    type A;
//    type B;

trait Contains<A, B> {
    fn contains(&self, _: &A, _: &B) -> bool;
    fn first(&self) -> i32;
    fn last(&self) -> i32;
}

impl Contains<i32, i32> for Container {
    fn contains(&self, number_1: &i32, number_2: &i32) -> bool {
        (&self.0 == number_1) && (&self.1 == number_2)
    }
    // Grab the first number.
    fn first(&self) -> i32 { self.0 }

    // Grab the last number.
    fn last(&self) -> i32 { self.1 }
}

fn difference<A, B, C: Contains<A, B>>(container: &C) -> i32 {
    container.last() - container.first()
}

fn main() {
    let number_1 = 3;
    let number_2 = 10;

    let container = Container(number_1, number_2);

    println!("Does container contain {} and {}: {}",
        &number_1, &number_2,
        container.contains(&number_1, &number_2));
    println!("First number: {}", container.first());
    println!("Last number: {}", container.last());
    
    println!("The difference is: {}", difference(&container));
}
```

## Default Generic Type Parameters
When we use generic type parameters, we can specify a default concrete type for the generic type. This eliminates the need for implementors of the trait to specify a concrete type if the default type works.

2. 🌟🌟
```rust,editable

use std::ops::Sub;

#[derive(Debug, PartialEq)]
struct Point<T> {
    x: T,
    y: T,
}

// FILL in the blank in three ways: two of them use the default generic  parameters, the other one not.
// Notice that the implementation uses the associated type `Output`.
impl __ {
    type Output = Self;

    fn sub(self, other: Self) -> Self::Output {
        Point {
            x: self.x - other.x,
            y: self.y - other.y,
        }
    }
}

fn main() {
    assert_eq!(Point { x: 2, y: 3 } - Point { x: 1, y: 0 },
        Point { x: 1, y: 3 });

    println!("Success!");
}
```

## Fully Qualified Syntax
Nothing in Rust prevents a trait from having a method with the same name as another trait’s method, nor does Rust prevent you from implementing both traits on one type. It’s also possible to implement a method directly on the type with the same name as methods from traits.

When calling methods with the same name, we have to use  Fully Qualified Syntax.

#### Example
```rust,editable
trait UsernameWidget {
    // Get the selected username out of this widget
    fn get(&self) -> String;
}

trait AgeWidget {
    // Get the selected age out of this widget
    fn get(&self) -> u8;
}

// A form with both a UsernameWidget and an AgeWidget.
struct Form {
    username: String,
    age: u8,
}

impl UsernameWidget for Form {
    fn get(&self) -> String {
        self.username.clone()
    }
}

impl AgeWidget for Form {
    fn get(&self) -> u8 {
        self.age
    }
}

fn main() {
    let form = Form{
        username: "rustacean".to_owned(),
        age: 28,
    };

    // If you uncomment this line, you'll get an error saying 
    // "multiple `get` found". Because, after all, there are multiple methods
    // named `get`.
    // println!("{}", form.get());
    
    let username = UsernameWidget::get(&form);
    assert_eq!("rustacean".to_owned(), username);
    let age = AgeWidget::get(&form); // You can also use `<Form as AgeWidget>::get`
    assert_eq!(28, age);

    println!("Success!");
}
```

#### Exercise
3. 🌟🌟
```rust,editable
trait Pilot {
    fn fly(&self) -> String;
}

trait Wizard {
    fn fly(&self) -> String;
}

struct Human;

impl Pilot for Human {
    fn fly(&self) -> String {
        String::from("This is your captain speaking.")
    }
}

impl Wizard for Human {
    fn fly(&self) -> String {
        String::from("Up!")
    }
}

impl Human {
    fn fly(&self) -> String {
        String::from("*waving arms furiously*")
    }
}

fn main() {
    let person = Human;

    assert_eq!(__, "This is your captain speaking.");
    assert_eq!(__, "Up!");

    assert_eq!(__, "*waving arms furiously*");

    println!("Success!");
}
```

## Supertraits
Sometimes, you might need one trait to use another trait’s functionality( like the "inheritance" in other languages ). In this case, you need to rely on the dependent trait also being implemented. The trait you rely on is a `supertrait` of the trait you’re implementing.

4. 🌟🌟🌟
```rust,editable

trait Person {
    fn name(&self) -> String;
}

// Person is a supertrait of Student.
// Implementing Student requires you to also impl Person.
trait Student: Person {
    fn university(&self) -> String;
}

trait Programmer {
    fn fav_language(&self) -> String;
}

// CompSciStudent (computer science student) is a subtrait of both Programmer 
// and Student. Implementing CompSciStudent requires you to impl both supertraits.
trait CompSciStudent: Programmer + Student {
    fn git_username(&self) -> String;
}

fn comp_sci_student_greeting(student: &dyn CompSciStudent) -> String {
    format!(
        "My name is {} and I attend {}. My favorite language is {}. My Git username is {}",
        student.name(),
        student.university(),
        student.fav_language(),
        student.git_username()
    )
}

struct CSStudent {
    name: String,
    university: String,
    fav_language: String,
    git_username: String
}

// IMPLEMENT the necessary traits for CSStudent to make the code work
impl ...

fn main() {
    let student = CSStudent {
        name: "Sunfei".to_string(),
        university: "XXX".to_string(),
        fav_language: "Rust".to_string(),
        git_username: "sunface".to_string()
    };

    // FILL in the blank
    println!("{}", comp_sci_student_greeting(__));
}
```

## Orphan Rules
We can’t implement external traits on external types. For example, we can’t implement the `Display` trait on `Vec<T>` within our own crate, because `Display` and `Vec<T>` are defined in the standard library and aren’t local to our crate. 

This restriction is often called the orphan rule, so named because the parent type is not present. This rule ensures that other people’s code can’t break your code and vice versa. 

It’s possible to get around this restriction using the newtype pattern, which involves creating a new type in a tuple struct.

5. 🌟🌟
```rust,editable
use std::fmt;

// DEFINE a newtype `Pretty` here


impl fmt::Display for Pretty {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "\"{}\"", self.0.clone() + ", world")
    }
}

fn main() {
    let w = Pretty("hello".to_string());
    println!("w = {}", w);
}
```

> You can find the solutions [here](https://github.com/sunface/rust-by-practice)(under the solutions path), but only use it when you need it :)

================================================
FILE: en/src/generics-traits/const-generics.md
================================================
# Const Generics
Const generics are generic arguments that range over constant values, rather than types or lifetimes. This allows, for instance, types to be parameterized by integers. In fact, there has been one example of const generic types since early on in Rust's development: the array types [T; N], for some type T and N: usize. However, there has previously been no way to abstract over arrays of an arbitrary size: if you wanted to implement a trait for arrays of any size, you would have to do so manually for each possible value. For a long time, even the standard library methods for arrays were limited to arrays of length at most 32 due to this problem.

## Examples
1. Here's an example of a type and implementation making use of const generics: a type wrapping a pair of arrays of the same size.
```rust,editable
struct ArrayPair<T, const N: usize> {
    left: [T; N],
    right: [T; N],
}

impl<T: Debug, const N: usize> Debug for ArrayPair<T, N> {
    // ...
}
```


2. Currently, const parameters may only be instantiated by const arguments of the following forms:

- A standalone const parameter.
- A literal (i.e. an integer, bool, or character).
- A concrete constant expression (enclosed by {}), involving no generic parameters.
  
```rust,editable
fn foo<const N: usize>() {}

fn bar<T, const M: usize>() {
    foo::<M>(); // Okay: `M` is a const parameter
    foo::<2021>(); // Okay: `2021` is a literal
    foo::<{20 * 100 + 20 * 10 + 1}>(); // Okay: const expression contains no generic parameters
    
    foo::<{ M + 1 }>(); // Error: const expression contains the generic parameter `M`
    foo::<{ std::mem::size_of::<T>() }>(); // Error: const expression contains the generic parameter `T`
    
    let _: [u8; M]; // Okay: `M` is a const parameter
    let _: [u8; std::mem::size_of::<T>()]; // Error: const expression contains the generic parameter `T`
}

fn main() {}
```

3. Const generics can also let us avoid some runtime checks.
```rust
/// A region of memory containing at least `N` `T`s.
pub struct MinSlice<T, const N: usize> {
    /// The bounded region of memory. Exactly `N` `T`s.
    pub head: [T; N],
    /// Zero or more remaining `T`s after the `N` in the bounded region.
    pub tail: [T],
}

fn main() {
    let slice: &[u8] = b"Hello, world";
    let reference: Option<&u8> = slice.get(6);
    // We know this value is `Some(b' ')`,
    // but the compiler can't know that.
    assert!(reference.is_some());

    let slice: &[u8] = b"Hello, world";
    // Length check is performed when we construct a MinSlice,
    // and it's known at compile time to be of length 12.
    // If the `unwrap()` succeeds, no more checks are needed
    // throughout the `MinSlice`'s lifetime.
    let minslice = MinSlice::<u8, 12>::from_slice(slice).unwrap();
    let value: u8 = minslice.head[6];
    assert_eq!(value, b' ')
}
```


## Exercises
1. 🌟🌟 `<T, const N: usize>` is part of the struct type, it means `Array<i32, 3>` and `Array<i32, 4>` are different types.
   
```rust,editable
struct Array<T, const N: usize> {
    data : [T; N]
}

fn main() {
    let arrays = [
        Array{
            data: [1, 2, 3],
        },
        Array {
            data: [1.0, 2.0, 3.0],
        },
        Array {
            data: [1, 2]
        }
    ];

    println!("Success!");
}
```

2. 🌟🌟 
```rust,editable

// Fill in the blanks to make it work.
fn print_array<__>(__) {
    println!("{:?}", arr);
}
fn main() {
    let arr = [1, 2, 3];
    print_array(arr);

    let arr = ["hello", "world"];
    print_array(arr);
}
```

3. 🌟🌟🌟 Sometimes we want to limit the size of a variable, e.g when using in embedding environments, then `const expressions` will fit your needs.
   
```rust,editable
#![allow(incomplete_features)]
#![feature(generic_const_exprs)]

fn check_size<T>(val: T)
where
    Assert<{ core::mem::size_of::<T>() < 768 }>: IsTrue,
{
    //...
}

// Fix the errors in main.
fn main() {
    check_size([0u8; 767]); 
    check_size([0i32; 191]);
    check_size(["hello你好"; __]); // Size of &str ?
    check_size([(); __].map(|_| "hello你好".to_string()));  // Size of String?
    check_size(['中'; __]); // Size of char ?

    println!("Success!");
}



pub enum Assert<const CHECK: bool> {}

pub trait IsTrue {}

impl IsTrue for Assert<true> {}
```

> You can find the solutions [here](https://github.com/sunface/rust-by-practice/blob/master/solutions/generics-traits/const-generics.md)(under the solutions path), but only use it when you need it :)

================================================
FILE: en/src/generics-traits/generics.md
================================================
# Generics

### Functions
1. 🌟🌟🌟
```rust,editable

// Fill in the blanks to make it work
struct A;          // Concrete type `A`.
struct S(A);       // Concrete type `S`.
struct SGen<T>(T); // Generic type `SGen`.

fn reg_fn(_s: S) {}

fn gen_spec_t(_s: SGen<A>) {}

fn gen_spec_i32(_s: SGen<i32>) {}

fn generic<T>(_s: SGen<T>) {}

fn main() {
    // Using the non-generic functions
    reg_fn(__);          // Concrete type.
    gen_spec_t(__);   // Implicitly specified type parameter `A`.
    gen_spec_i32(__); // Implicitly specified type parameter `i32`.

    // Explicitly specified type parameter `char` to `generic()`.
    generic::<char>(__);

    // Implicitly specified type parameter `char` to `generic()`.
    generic(__);

    println!("Success!");
}
```

2. 🌟🌟 A function call with explicitly specified type parameters looks like: `fun::<A, B, ...>()`.
```rust,editable

// Implement the generic function below.
fn sum

fn main() {
    assert_eq!(5, sum(2i8, 3i8));
    assert_eq!(50, sum(20, 30));
    assert_eq!(2.46, sum(1.23, 1.23));

    println!("Success!");
}
```


### Struct and `impl`

3. 🌟
```rust,editable

// Implement struct Point to make it work.


fn main() {
    let integer = Point { x: 5, y: 10 };
    let float = Point { x: 1.0, y: 4.0 };

    println!("Success!");
}
```

4. 🌟🌟
```rust,editable

// Modify this struct to make the code work
struct Point<T> {
    x: T,
    y: T,
}

fn main() {
    // DON'T modify this code.
    let p = Point{x: 5, y : "hello".to_string()};

    println!("Success!");
}
```

5. 🌟🌟
```rust,editable

// Add generic for Val to make the code work, DON'T modify the code in `main`.
struct Val {
    val: f64,
}

impl Val {
    fn value(&self) -> &f64 {
        &self.val
    }
}


fn main() {
    let x = Val{ val: 3.0 };
    let y = Val{ val: "hello".to_string()};
    println!("{}, {}", x.value(), y.value());
}
```

### Method
6. 🌟🌟🌟 

```rust,editable
struct Point<T, U> {
    x: T,
    y: U,
}

impl<T, U> Point<T, U> {
    // Implement mixup to make it work, DON'T modify other code.
    fn mixup
}

fn main() {
    let p1 = Point { x: 5, y: 10 };
    let p2 = Point { x: "Hello", y: '中'};

    let p3 = p1.mixup(p2);

    assert_eq!(p3.x, 5);
    assert_eq!(p3.y, '中');

    println!("Success!");
}
```

7. 🌟🌟
```rust,editable

// Fix the errors to make the code work.
struct Point<T> {
    x: T,
    y: T,
}

impl Point<f32> {
    fn distance_from_origin(&self) -> f32 {
        (self.x.powi(2) + self.y.powi(2)).sqrt()
    }
}

fn main() {
    let p = Point{x: 5, y: 10};
    println!("{}",p.distance_from_origin());
}
```

> You can find the solutions [here](https://github.com/sunface/rust-by-practice/blob/master/solutions/generics-traits/generics.md)(under the solutions path), but only use it when you need it



================================================
FILE: en/src/generics-traits/intro.md
================================================
# Generics and Traits
Learning resources: 
- English: [Rust Book 10.1, 10.2](https://doc.rust-lang.org/book/ch10-00-generics.html)
- 简体中文: [Rust语言圣经 - 模式匹配](https://course.rs/basic/trait/intro.html)




================================================
FILE: en/src/generics-traits/trait-object.md
================================================
# Trait Object
In [traits chapter](https://practice.rs/generics-traits/traits.html#returning-types-that-implement-traits) we have seen that we can't use `impl Trait` when returning multiple types.

Another limitation of arrays is that they can only store elements of one type. Using enums is not a bad solution when we have a fixed set of types at compile time, but trait objects would be more flexible and powerful.

## Returning Traits with dyn
The Rust compiler needs to know how much space a function's return type requires. Because the different implementations of a trait probably uses different amounts of memory, functions need to either return a concrete type or the same type when using  `impl Trait`, or return a trait object with `dyn`.

1. 🌟🌟🌟
```rust,editable

trait Bird {
    fn quack(&self) -> String;
}

struct Duck;
impl Duck {
    fn swim(&self) {
        println!("Look, the duck is swimming")
    }
}
struct Swan;
impl Swan {
    fn fly(&self) {
        println!("Look, the duck.. oh sorry, the swan is flying")
    }
}

impl Bird for Duck {
    fn quack(&self) -> String{
        "duck duck".to_string()
    }
}

impl Bird for Swan {
    fn quack(&self) -> String{
        "swan swan".to_string()
    }
}

fn main() {
    // FILL in the blank.
    let duck = __;
    duck.swim();

    let bird = hatch_a_bird(2);
    // This bird has forgotten how to swim, so below line will cause an error.
    // bird.swim();
    // But it can quak.
    assert_eq!(bird.quack(), "duck duck");

    let bird = hatch_a_bird(1);
    // This bird has forgotten how to fly, so below line will cause an error.
    // bird.fly();
    // But it can quak too.
    assert_eq!(bird.quack(), "swan swan");

    println!("Success!");
}   

// IMPLEMENT this function.
fn hatch_a_bird...

```
## Array with trait objects
2. 🌟🌟
```rust,editable 
trait Bird {
    fn quack(&self);
}

struct Duck;
impl Duck {
    fn fly(&self) {
        println!("Look, the duck is flying")
    }
}
struct Swan;
impl Swan {
    fn fly(&self) {
        println!("Look, the duck.. oh sorry, the swan is flying")
    }
}

impl Bird for Duck {
    fn quack(&self) {
        println!("{}", "duck duck");
    }
}

impl Bird for Swan {
    fn quack(&self) {
        println!("{}", "swan swan");
    }
}

fn main() {
    // FILL in the blank to make the code work.
    let birds __;

    for bird in birds {
        bird.quack();
        // When duck and swan turn into Birds, they all forgot how to fly, only remember how to quack.
        // So, the code below will cause an error.
        // bird.fly();
    }
}
```


## `&dyn` and `Box<dyn>`

3. 🌟🌟
```rust,editable

// FILL in the blanks.
trait Draw {
    fn draw(&self) -> String;
}

impl Draw for u8 {
    fn draw(&self) -> String {
        format!("u8: {}", *self)
    }
}

impl Draw for f64 {
    fn draw(&self) -> String {
        format!("f64: {}", *self)
    }
}

fn main() {
    let x = 1.1f64;
    let y = 8u8;

    // Draw x.
    draw_with_box(__);

    // Draw y.
    draw_with_ref(&y);

    println!("Success!");
}

fn draw_with_box(x: Box<dyn Draw>) {
    x.draw();
}

fn draw_with_ref(x: __) {
    x.draw();
}
```

## Static and Dynamic dispatch
When we use trait bounds on generics, the compiler generates nongeneric implementations of functions and methods for each concrete type that we use in place of a generic type parameter. The code that results from monomorphization is doing static dispatch, which is when the compiler knows what method you’re calling at compile time. 

When we use trait objects, Rust must use dynamic dispatch. The compiler doesn’t know all the types that might be used with the code that is using trait objects, so it doesn’t know which method implemented on which type to call. Instead, at runtime, Rust uses the pointers inside the trait object to know which method to call. There is a runtime cost when this lookup happens that doesn’t occur with static dispatch. Dynamic dispatch also prevents the compiler from choosing to inline a method’s code, which in turn prevents some optimizations. 

However, we do get extra flexibility when using dynamic dispatch.

4. 🌟🌟
```rust,editable

trait Foo {
    fn method(&self) -> String;
}

impl Foo for u8 {
    fn method(&self) -> String { format!("u8: {}", *self) }
}

impl Foo for String {
    fn method(&self) -> String { format!("string: {}", *self) }
}

// IMPLEMENT below with generics.
fn static_dispatch...

// Implement below with trait objects.
fn dynamic_dispatch...

fn main() {
    let x = 5u8;
    let y = "Hello".to_string();

    static_dispatch(x);
    dynamic_dispatch(&y);

    println!("Success!");
}
```

## Object safe
You can only make object-safe traits into trait objects. A trait is object safe if all the methods defined in the trait have the following properties:

- The return type isn’t `Self`.
- There are no generic type parameters.

5. 🌟🌟🌟🌟
```rust,editable

// Use at least two approaches to make it work.
// DON'T add/remove any code line.
trait MyTrait {
    fn f(&self) -> Self;
}

impl MyTrait for u32 {
    fn f(&self) -> Self { 42 }
}

impl MyTrait for String {
    fn f(&self) -> Self { self.clone() }
}

fn my_function(x: Box<dyn MyTrait>)  {
    x.f()
}

fn main() {
    my_function(Box::new(13_u32));
    my_function(Box::new(String::from("abc")));

    println!("Success!");
}
```

> You can find the solutions [here](https://github.com/sunface/rust-by-practice/blob/master/solutions/generics-traits/trait-object.md)(under the solutions path), but only use it when you need it :)


================================================
FILE: en/src/generics-traits/traits.md
================================================
# Traits
A trait tells the Rust compiler about functionality a particular type has and can share with other types. We can use traits to define shared behavior in an abstract way. We can use trait bounds to specify that a generic type can be any type that has certain behavior.

> Note: Traits are similar to interfaces in other languages, although with some differences.

## Examples
```rust,editable

struct Sheep { naked: bool, name: String }

trait Animal {
    // Associated function signature; `Self` refers to the implementor type.
    fn new(name: String) -> Self;

    // Method signatures; these will return a string.
    fn name(&self) -> String;
    
    fn noise(&self) -> String;

    // Traits can provide default method definitions.
    fn talk(&self) {
        println!("{} says {}", self.name(), self.noise());
    }
}

impl Sheep {
    fn is_naked(&self) -> bool {
        self.naked
    }

    fn shear(&mut self) {
        if self.is_naked() {
            // Implementor methods can use the implementor's trait methods.
            println!("{} is already naked...", self.name());
        } else {
            println!("{} gets a haircut!", self.name);

            self.naked = true;
        }
    }
}

// Implement the `Animal` trait for `Sheep`.
impl Animal for Sheep {
    // `Self` is the implementor type: `Sheep`.
    fn new(name: String) -> Sheep {
        Sheep { name: name, naked: false }
    }

    fn name(&self) -> String {
        self.name.clone()
    }

    fn noise(&self) -> String {
        if self.is_naked() {
            "baaaaah?".to_string()
        } else {
            "baaaaah!".to_string()
        }
    }
    
    // Default trait methods can be overridden.
    fn talk(&self) {
        // For example, we can add some quiet contemplation.
        println!("{} pauses briefly... {}", self.name, self.noise());
    }
}

fn main() {
    // Type annotation is necessary in this case.
    let mut dolly: Sheep = Animal::new("Dolly".to_string());
    // TODO ^ Try removing the type annotations.

    dolly.talk();
    dolly.shear();
    dolly.talk();
}
```

## Exercises
1. 🌟🌟
```rust,editable

// Fill in the two impl blocks to make the code work.
// DON'T modify the code in `main`.
trait Hello {
    fn say_hi(&self) -> String {
        String::from("hi")
    }

    fn say_something(&self) -> String;
}

struct Student {}
impl Hello for Student {
}
struct Teacher {}
impl Hello for Teacher {
}

fn main() {
    let s = Student {};
    assert_eq!(s.say_hi(), "hi");
    assert_eq!(s.say_something(), "I'm a good student");

    let t = Teacher {};
    assert_eq!(t.say_hi(), "Hi, I'm your new teacher");
    assert_eq!(t.say_something(), "I'm not a bad teacher");

    println!("Success!");
}
```

### Derive
The compiler is capable of providing basic implementations for some traits via
the `#[derive]` attribute. For more info, please visit [here](https://doc.rust-lang.org/book/appendix-03-derivable-traits.html).

2. 🌟🌟
```rust,editable

// `Centimeters`, a tuple struct that can be compared
#[derive(PartialEq, PartialOrd)]
struct Centimeters(f64);

// `Inches`, a tuple struct that can be printed
#[derive(Debug)]
struct Inches(i32);

impl Inches {
    fn to_centimeters(&self) -> Centimeters {
        let &Inches(inches) = self;

        Centimeters(inches as f64 * 2.54)
    }
}

// ADD some attributes to make the code work!
// DON'T modify other code!
struct Seconds(i32);

fn main() {
    let _one_second = Seconds(1);

    println!("One second looks like: {:?}", _one_second);
    let _this_is_true = (_one_second == _one_second);
    let _this_is_false = (_one_second > _one_second);

    let foot = Inches(12);

    println!("One foot equals {:?}", foot);

    let meter = Centimeters(100.0);

    let cmp =
        if foot.to_centimeters() < meter {
            "smaller"
        } else {
            "bigger"
        };

    println!("One foot is {} than one meter.", cmp);
}
```


### Operator
In Rust, many of the operators can be overloaded via traits. That is, some operators can be used to accomplish different tasks based on their input arguments. This is possible because operators are syntactic sugar for method calls. For example, the + operator in a + b calls the add method (as in a.add(b)). This add method is part of the Add trait. Hence, the + operator can be used by any implementor of the Add trait.

3. 🌟🌟
```rust,editable

use std::ops;

// Implement fn multiply to make the code work.
// As mentioned above, `+` needs `T` to implement `std::ops::Add` Trait.
// So, what about `*`?  You can find the answer here: https://doc.rust-lang.org/core/ops/
fn multiply

fn main() {
    assert_eq!(6, multiply(2u8, 3u8));
    assert_eq!(5.0, multiply(1.0, 5.0));

    println!("Success!");
}
```

4. 🌟🌟🌟
```rust,editable

// Fix the errors, DON'T modify the code in `main`.
use std::ops;

struct Foo;
struct Bar;

struct FooBar;

struct BarFoo;

// The `std::ops::Add` trait is used to specify the functionality of `+`.
// Here, we make `Add<Bar>` - the trait for addition with a RHS of type `Bar`.
// The following block implements the operation: Foo + Bar = FooBar
impl ops::Add<Bar> for Foo {
    type Output = FooBar;

    fn add(self, _rhs: Bar) -> FooBar {
        FooBar
    }
}

impl ops::Sub<Foo> for Bar {
    type Output = BarFoo;

    fn sub(self, _rhs: Foo) -> BarFoo {
        BarFoo
    }
}

fn main() {
    // DON'T modify the code below.
    // You need to derive some trait for FooBar to make it comparable.
    assert_eq!(Foo + Bar, FooBar);
    assert_eq!(Foo - Bar, BarFoo);

    println!("Success!");
}
```

### Use trait as function parameters
Instead of a concrete type for the item parameter, we specify the impl keyword and the trait name. This parameter accepts any type that implements the specified trait. 

5. 🌟🌟🌟
```rust,editable

// Implement `fn summary` to make the code work.
// Fix the errors without removing any code line
trait Summary {
    fn summarize(&self) -> String;
}

#[derive(Debug)]
struct Post {
    title: String,
    author: String,
    content: String,
}

impl Summary for Post {
    fn summarize(&self) -> String {
        format!("The author of post {} is {}", self.title, self.author)
    }
}

#[derive(Debug)]
struct Weibo {
    username: String,
    content: String,
}

impl Summary for Weibo {
    fn summarize(&self) -> String {
        format!("{} published a weibo {}", self.username, self.content)
    }
}

fn main() {
    let post = Post {
        title: "Popular Rust".to_string(),
        author: "Sunface".to_string(),
        content: "Rust is awesome!".to_string(),
    };
    let weibo = Weibo {
        username: "sunface".to_string(),
        content: "Weibo seems to be worse than Tweet".to_string(),
    };

    summary(post);
    summary(weibo);

    println!("{:?}", post);
    println!("{:?}", weibo);
}

// Implement `fn summary` below.

```

### Returning Types that Implement Traits
We can also use the impl Trait syntax in the return position to return a value of some type that implements a trait.

However, you can only use impl Trait if you’re returning a single type, use Trait Objects instead when you really need to return several types.

6. 🌟🌟
```rust,editable

struct Sheep {}
struct Cow {}

trait Animal {
    fn noise(&self) -> String;
}

impl Animal for Sheep {
    fn noise(&self) -> String {
        "baaaaah!".to_string()
    }
}

impl Animal for Cow {
    fn noise(&self) -> String {
        "moooooo!".to_string()
    }
}

// Returns some struct that implements Animal, but we don't know which one at compile time.
// FIX the errors here, you can make a fake random, or you can use trait object.
fn random_animal(random_number: f64) -> impl Animal {
    if random_number < 0.5 {
        Sheep {}
    } else {
        Cow {}
    }
}

fn main() {
    let random_number = 0.234;
    let animal = random_animal(random_number);
    println!("You've randomly chosen an animal, and it says {}", animal.noise());
}
```

### Trait bound
The `impl Trait` syntax works for straightforward cases but is actually syntax sugar for a longer form, which is called a trait bound.

When working with generics, the type parameters often must use traits as bounds to stipulate what functionality a type implements. 

7. 🌟🌟
```rust,editable
fn main() {
    assert_eq!(sum(1, 2), 3);
}

// Implement `fn sum` with trait bound in two ways.
fn sum<T>(x: T, y: T) -> T {
    x + y
}
```
8. 🌟🌟
```rust,editable

// FIX the errors.
struct Pair<T> {
    x: T,
    y: T,
}

impl<T> Pair<T> {
    fn new(x: T, y: T) -> Self {
        Self {
            x,
            y,
        }
    }
}

impl<T: std::fmt::Debug + PartialOrd> Pair<T> {
    fn cmp_display(&self) {
        if self.x >= self.y {
            println!("The largest member is x = {:?}", self.x);
        } else {
            println!("The largest member is y = {:?}", self.y);
        }
    }
}

struct Unit(i32);

fn main() {
    let pair = Pair{
        x: Unit(1),
        y: Unit(3)
    };

    pair.cmp_display();
}
```

9. 🌟🌟🌟
```rust,editable

// Fill in the blanks to make it work
fn example1() {
    // `T: Trait` is the commonly used way.
    // `T: Fn(u32) -> u32` specifies that we can only pass a closure to `T`.
    struct Cacher<T: Fn(u32) -> u32> {
        calculation: T,
        value: Option<u32>,
    }

    impl<T: Fn(u32) -> u32> Cacher<T> {
        fn new(calculation: T) -> Cacher<T> {
            Cacher {
                calculation,
                value: None,
            }
        }

        fn value(&mut self, arg: u32) -> u32 {
            match self.value {
                Some(v) => v,
                None => {
                    let v = (self.calculation)(arg);
                    self.value = Some(v);
                    v
                },
            }
        }
    }

    let mut cacher = Cacher::new(|x| x+1);
    assert_eq!(cacher.value(10), __);
    assert_eq!(cacher.value(15), __);
}


fn example2() {
    // We can also use `where` to construct `T`
    struct Cacher<T>
        where T: Fn(u32) -> u32,
    {
        calculation: T,
        value: Option<u32>,
    }

    impl<T> Cacher<T>
        where T: Fn(u32) -> u32,
    {
        fn new(calculation: T) -> Cacher<T> {
            Cacher {
                calculation,
                value: None,
            }
        }

        fn value(&mut self, arg: u32) -> u32 {
            match self.value {
                Some(v) => v,
                None => {
                    let v = (self.calculation)(arg);
                    self.value = Some(v);
                    v
                },
            }
        }
    }

    let mut cacher = Cacher::new(|x| x+1);
    assert_eq!(cacher.value(20), __);
    assert_eq!(cacher.value(25), __);
}



fn main() {
    example1();
    example2();

    println!("Success!");
}
```

> You can find the solutions [here](https://github.com/sunface/rust-by-practice/blob/master/solutions/generics-traits/traits.md)(under the solutions path), but only use it when you need it :)


================================================
FILE: en/src/global-variables.md
================================================
# Global variables


================================================
FILE: en/src/lifetime/advance.md
================================================
# Advance lifetime

## Trait Bounds
Just like generic types can be bounded, lifetimes can also be bounded as below:
- `T: 'a`,all references in `T` must outlive the lifetime `'a`
- `T: Trait + 'a`: `T` must implement trait `Trait` and all references in `T` must outlive `'a`

**Example**
```rust,editable
use std::fmt::Debug; // Trait to bound with.

#[derive(Debug)]
struct Ref<'a, T: 'a>(&'a T);
// `Ref` contains a reference to a generic type `T` that has
// an unknown lifetime `'a`. `T` is bounded such that any
// *references* in `T` must outlive `'a`. Additionally, the lifetime
// of `Ref` may not exceed `'a`.

// A generic function which prints using the `Debug` trait.
fn print<T>(t: T) where
    T: Debug {
    println!("`print`: t is {:?}", t);
}

// Here a reference to `T` is taken where `T` implements
// `Debug` and all *references* in `T` outlive `'a`. In
// addition, `'a` must outlive the function.
fn print_ref<'a, T>(t: &'a T) where
    T: Debug + 'a {
    println!("`print_ref`: t is {:?}", t);
}

fn main() {
    let x = 7;
    let ref_x = Ref(&x);

    print_ref(&ref_x);
    print(ref_x);
}
```

1. 🌟
```rust,editable
/* Annotate struct with lifetime:
1. `r` and `s` must have different lifetimes
2. lifetime of `s` is bigger than that of 'r'
*/
struct DoubleRef<T> {
    r: &T,
    s: &T
}
fn main() {
    println!("Success!")
}
```


2. 🌟🌟
```rust,editable
/* Adding trait bounds to make it work */
struct ImportantExcerpt<'a> {
    part: &'a str,
}

impl<'a, 'b> ImportantExcerpt<'a> {
    fn announce_and_return_part(&'a self, announcement: &'b str) -> &'b str {
        println!("Attention please: {}", announcement);
        self.part
    }
}

fn main() {
    println!("Success!")
}
```

3. 🌟🌟
```rust,editable
/* Adding trait bounds to make it work */
fn f<'a, 'b>(x: &'a i32, mut y: &'b i32) {
    y = x;                      
    let r: &'b &'a i32 = &&0;   
}

fn main() {
    println!("Success!")
}
```

## HRTB(Higher-ranked trait bounds)
Type bounds may be higher ranked over lifetimes. These bounds specify a bound is true for all lifetimes. For example, a bound such as `for<'a> &'a T: PartialEq<i32>` would require an implementation like: 

```rust
impl<'a> PartialEq<i32> for &'a T {
    // ...
}
```

and could then be used to compare a `&'a T` with any lifetime to an `i32`.

Only a higher-ranked bound can be used here, because the lifetime of the reference is shorter than any possible lifetime parameter on the function.

4. 🌟🌟🌟
```rust,editable
/* Adding HRTB to make it work!*/
fn call_on_ref_zero<'a, F>(f: F) where F: Fn(&'a i32) {
    let zero = 0;
    f(&zero);
}

fn main() {
    println!("Success!");
}
```
## NLL (Non-Lexical Lifetime)
Before explaining NLL, let's see some code first:
```rust
fn main() {
   let mut s = String::from("hello");

    let r1 = &s;
    let r2 = &s;
    println!("{} and {}", r1, r2);

    let r3 = &mut s;
    println!("{}", r3);
}
```

Based on our current knowledge, this code will cause en error due to violating the borrowing rules in Rust.

But if you `cargo run` it, then everything will be ok, so what's going on here?

The ability of the compiler to tell that a reference is no longer used at a point before the end of the scope, is called **Non-Lexical Lifetimes** (**NLL** for short).

With this ability the compiler knows when is the last time that a reference is used and optimizing the borrowing rules based on this knowledge.

```rust
let mut u = 0i32;
let mut v = 1i32;
let mut w = 2i32;

// lifetime of `a` = α ∪ β ∪ γ
let mut a = &mut u;     // --+ α. lifetime of `&mut u`  --+ lexical "lifetime" of `&mut u`,`&mut u`, `&mut w` and `a`
use(a);                 //   |                            |
*a = 3; // <-----------------+                            |
...                     //                                |
a = &mut v;             // --+ β. lifetime of `&mut v`    |
use(a);                 //   |                            |
*a = 4; // <-----------------+                            |
...                     //                                |
a = &mut w;             // --+ γ. lifetime of `&mut w`    |
use(a);                 //   |                            |
*a = 5; // <-----------------+ <--------------------------+
```

## Reborrow
After learning NLL, we can easily understand reborrow now.

**Example**
```rust
#[derive(Debug)]
struct Point {
    x: i32,
    y: i32,
}

impl Point {
    fn move_to(&mut self, x: i32, y: i32) {
        self.x = x;
        self.y = y;
    }
}

fn main() {
    let mut p = Point { x: 0, y: 0 };
    let r = &mut p;
    // Here comes the reborrow
    let rr: &Point = &*r;

    println!("{:?}", rr); // Reborrow ends here, NLL introduced

    // Reborrow is over, we can continue using `r` now
    r.move_to(10, 10);
    println!("{:?}", r);
}
```


5. 🌟🌟
```rust,editable
/* Make it work by reordering some code */
fn main() {
    let mut data = 10;
    let ref1 = &mut data;
    let ref2 = &mut *ref1;

    *ref1 += 1;
    *ref2 += 2;

    println!("{}", data);
}
```


## Unbound lifetime
See more info in [Nomicon - Unbounded Lifetimes](https://doc.rust-lang.org/nomicon/unbounded-lifetimes.html).


## More elision rules

```rust
impl<'a> Reader for BufReader<'a> {
    // 'a is not used in the following methods
}

// can be written as :
impl Reader for BufReader<'_> {
    
}
```

```rust
// Rust 2015
struct Ref<'a, T: 'a> {
    field: &'a T
}

// Rust 2018
struct Ref<'a, T> {
    field: &'a T
}
```


## A difficult exercise

6. 🌟🌟🌟🌟
```rust,editable
/* Make it work */
struct Interface<'a> {
    manager: &'a mut Manager<'a>
}

impl<'a> Interface<'a> {
    pub fn noop(self) {
        println!("interface consumed");
    }
}

struct Manager<'a> {
    text: &'a str
}

struct List<'a> {
    manager: Manager<'a>,
}

impl<'a> List<'a> {
    pub fn get_interface(&'a mut self) -> Interface {
        Interface {
            manager: &mut self.manager
        }
    }
}

fn main() {
    let mut list = List {
        manager: Manager {
            text: "hello"
        }
    };

    list.get_interface().noop();

    println!("Interface should be dropped here and the borrow released");

    use_list(&list);
}

fn use_list(list: &List) {
    println!("{}", list.manager.text);
}
```

> You can find the solutions [here](https://github.com/sunface/rust-by-practice/blob/master/solutions/lifetime/advance.md)(under the solutions path), but only use it when you need it :)


================================================
FILE: en/src/lifetime/basic.md
================================================
## Lifetime
The compiler uses lifetime to ensure all borrows are valid. Typically, a variable's lifetime begins when it is created and ends when it is destroyed.

## The scope of lifetime
1. 🌟
```rust,editable
/* Annotate the lifetime of `i` and `borrow2` */

// Lifetimes are annotated below with lines denoting the creation
// and destruction of each variable.
// `i` has the longest lifetime because its scope entirely encloses 
// both `borrow1` and `borrow2`. The duration of `borrow1` compared 
// to `borrow2` is irrelevant since they are disjoint.
fn main() {
    let i = 3;                                             
    {                                                    
        let borrow1 = &i; // `borrow1` lifetime starts. ──┐
        //                                                │
        println!("borrow1: {}", borrow1); //              │
    } // `borrow1 ends. ──────────────────────────────────┘
    {                                                    
        let borrow2 = &i; 
                                                        
        println!("borrow2: {}", borrow2);               
    }                                                   
}   
```

2. 🌟🌟

**Example**
```rust
{
    let x = 5;            // ----------+-- 'b
                          //           |
    let r = &x;           // --+-- 'a  |
                          //   |       |
    println!("r: {}", r); //   |       |
                          // --+       |
}                         // ----------+
```


```rust,editable
/* Annotate `r` and `x` as above, and explain why this code fails to compile, in the lifetime aspect. */

fn main() {  
    {
        let r;                // ---------+-- 'a
                              //          |
        {                     //          |
            let x = 5;        // -+-- 'b  |
            r = &x;           //  |       |
        }                     // -+       |
                              //          |
        println!("r: {}", r); //          |
    }                         // ---------+
}
```

## Lifetime annotating
The **borrow checker uses explicit lifetime annotations** to determine how long a reference should be valid. 

But for us users, in most cases, there is no need to annotate the lifetime, because there are several elision rules, before learning these rules, we need to know how to annotate lifetime manually.

#### Function
Ignoring elision rules, lifetimes in function signatures have a few constraints:

- Any reference must have an annotated lifetime
- Any reference being returned must have the same lifetime as one of the inputs or be static

**Example**
```rust,editable
// One input reference with lifetime `'a` which must live
// at least as long as the function.
fn print_one<'a>(x: &'a i32) {
    println!("`print_one`: x is {}", x);
}

// Mutable references are possible with lifetimes as well.
fn add_one<'a>(x: &'a mut i32) {
    *x += 1;
}

// Multiple elements with different lifetimes. In this case, it
// would be fine for both to have the same lifetime `'a`, but
// in more complex cases, different lifetimes may be required.
fn print_multi<'a, 'b>(x: &'a i32, y: &'b i32) {
    println!("`print_multi`: x is {}, y is {}", x, y);
}

// Returning references that have been passed in is acceptable.
// However, the correct lifetime must be returned.
fn pass_x<'a, 'b>(x: &'a i32, _: &'b i32) -> &'a i32 { x }

fn main() {
    let x = 7;
    let y = 9;
    
    print_one(&x);
    print_multi(&x, &y);
    
    let z = pass_x(&x, &y);
    print_one(z);

    let mut t = 3;
    add_one(&mut t);
    print_one(&t);
}
```

3. 🌟
```rust,editable
/* Make it work by adding proper lifetime annotation */
fn longest(x: &str, y: &str) -> &str {
    if x.len() > y.len() {
        x
    } else {
        y
    }
}

fn main() {}
```
4. 🌟🌟🌟
```rust,editable
// `'a` must live longer than the function.
// Here, `&String::from("foo")` would create a `String`, followed by a
// reference. Then the data is dropped upon exiting the scope, leaving
// a reference to invalid data to be returned.

/* Fix the error in three ways  */
fn invalid_output<'a>() -> &'a String { 
    &String::from("foo") 
}

fn main() {
}
```

5. 🌟🌟
```rust,editable
// `print_refs` takes two references to `i32` which have different
// lifetimes `'a` and `'b`. These two lifetimes must both be at
// least as long as the function `print_refs`.
fn print_refs<'a, 'b>(x: &'a i32, y: &'b i32) {
    println!("x is {} and y is {}", x, y);
}

/* Make it work */
// A function which takes no arguments, but has a lifetime parameter `'a`.
fn failed_borrow<'a>() {
    let _x = 12;

    // ERROR: `_x` does not live long enough
    let y: &'a i32 = &_x;
    // Attempting to use the lifetime `'a` as an explicit type annotation 
    // inside the function will fail because the lifetime of `&_x` is shorter
    // than `'a` . A short lifetime cannot be coerced into a longer one.
}

fn main() {
    let (four, nine) = (4, 9);
    
    // Borrows (`&`) of both variables are passed into the function.
    print_refs(&four, &nine);
    // Any input which is borrowed must outlive the borrower. 
    // In other words, the lifetime of `four` and `nine` must 
    // be longer than that of `print_refs`.
    
    failed_borrow();
    // `failed_borrow` contains no references to force `'a` to be 
    // longer than the lifetime of the function, but `'a` is longer.
    // Because the lifetime is never constrained, it defaults to `'static`.
}
```

#### Structs
6. 🌟
```rust,editable
/* Make it work by adding proper lifetime annotation */

// A type `Borrowed` which houses a reference to an
// `i32`. The reference to `i32` must outlive `Borrowed`.
#[derive(Debug)]
struct Borrowed(&i32);

// Similarly, both references here must outlive this structure.
#[derive(Debug)]
struct NamedBorrowed {
    x: &i32,
    y: &i32,
}

// An enum which is either an `i32` or a reference to one.
#[derive(Debug)]
enum Either {
    Num(i32),
    Ref(&i32),
}

fn main() {
    let x = 18;
    let y = 15;

    let single = Borrowed(&x);
    let double = NamedBorrowed { x: &x, y: &y };
    let reference = Either::Ref(&x);
    let number    = Either::Num(y);

    println!("x is borrowed in {:?}", single);
    println!("x and y are borrowed in {:?}", double);
    println!("x is borrowed in {:?}", reference);
    println!("y is *not* borrowed in {:?}", number);
}
```


7. 🌟🌟
```rust,editable
/* Make it work */

#[derive(Debug)]
struct NoCopyType {}

#[derive(Debug)]
struct Example<'a, 'b> {
    a: &'a u32,
    b: &'b NoCopyType
}

fn main()
{ 
  /* 'a tied to fn-main stackframe */
  let var_a = 35;
  let example: Example;
  
  {
    /* Lifetime 'b tied to new stackframe/scope */ 
    let var_b = NoCopyType {};
    
    /* fixme */
    example = Example { a: &var_a, b: &var_b };
  }
  
  println!("(Success!) {:?}", example);
}
```


8. 🌟🌟
```rust,editable

#[derive(Debug)]
struct NoCopyType {}

#[derive(Debug)]
#[allow(dead_code)]
struct Example<'a, 'b> {
    a: &'a u32,
    b: &'b NoCopyType
}

/* Fix function signature */
fn fix_me(foo: &Example) -> &NoCopyType
{ foo.b }

fn main()
{
    let no_copy = NoCopyType {};
    let example = Example { a: &1, b: &no_copy };
    fix_me(&example);
    println!("Success!")
}
```

## Method
Methods are annotated similarly to functions.

**Example**
```rust,editable
struct Owner(i32);

impl Owner {
    // Annotate lifetimes as in a standalone function.
    fn add_one<'a>(&'a mut self) { self.0 += 1; }
    fn print<'a>(&'a self) {
        println!("`print`: {}", self.0);
    }
}

fn main() {
    let mut owner = Owner(18);

    owner.add_one();
    owner.print();
}
```

9. 🌟🌟
```rust,editable
/* Make it work by adding proper lifetime annotations */
struct ImportantExcerpt {
    part: &str,
}

impl ImportantExcerpt {
    fn level(&'a self) -> i32 {
        3
    }
}

fn main() {}
```

## Elision
Some lifetime patterns are so common that borrow checker will allow you to omit them to save typing and improve readability.

This is known as **Elision**. Elision exist in Rust only because these patterns are common.

For a more comprehensive understanding of elision, please see [lifetime elision](https://doc.rust-lang.org/book/ch10-03-lifetime-syntax.html#lifetime-elision) in the official book.

10. 🌟🌟
```rust,editable
/* Remove all the lifetimes that can be elided */

fn input<'a>(x: &'a i32) {
    println!("`annotated_input`: {}", x);
}

fn pass<'a>(x: &'a i32) -> &'a i32 { x }

fn longest<'a, 'b>(x: &'a str, y: &'b str) -> &'a str {
    x
}

struct Owner(i32);

impl Owner {
    // Annotate lifetimes as in a standalone function.
    fn add_one<'a>(&'a mut self) { self.0 += 1; }
    fn print<'a>(&'a self) {
        println!("`print`: {}", self.0);
    }
}

struct Person<'a> {
    age: u8,
    name: &'a str,
}

enum Either<'a> {
    Num(i32),
    Ref(&'a i32),
}

fn main() {}
```
> You can find the solutions [here](https://github.com/sunface/rust-by-practice/blob/master/solutions/lifetime/basic.md)(under the solutions path), but only use it when you need it :)


================================================
FILE: en/src/lifetime/intro.md
================================================
# Lifetime
Learning resources: 
- English: [Rust Book 10.3](https://doc.rust-lang.org/book/ch10-03-lifetime-syntax.html)
- 简体中文: [Rust语言圣经 - 生命周期](https://course.rs/advance/lifetime/intro.html)



================================================
FILE: en/src/lifetime/static.md
================================================
# &'static and T: 'static
`'static` is a reserved lifetime name, you might have encountered it several times:
```rust
// A reference with 'static lifetime:
let s: &'static str = "hello world";

// 'static as part of a trait bound:
fn generic<T>(x: T) where T: 'static {}
```

Though they are all `'static`, but subtly different.

## &'static
As a reference lifetime, `&'static` indicates the data pointed to by the reference lives as long as the running program. But it can still be coerced to a shorter lifetime.



1. 🌟🌟 There are several ways to make a variable with `'static` lifetime, two of them are stored in the read-only memory of the binary.

```rust,editable

/* Fill in the blank in two ways */
fn main() {
    __;
    need_static(v);

    println!("Success!")
}

fn need_static(r : &'static str) {
    assert_eq!(r, "hello");
}
```

2. 🌟🌟🌟🌟 Another way to make `'static` lifetime is using `Box::leak`
```rust,editable
#[derive(Debug)]
struct Config {
    a: String,
    b: String,
}
static mut config: Option<&mut Config> = None;

/* Make it work without changing the function signatures of `init`*/
fn init() -> Option<&'static mut Config> {
    Some(&mut Config {
        a: "A".to_string(),
        b: "B".to_string(),
    })
}


fn main() {
    unsafe {
        config = init();

        println!("{:?}",config)
    }
}
```

3. 🌟 `&'static` only indicates that the data can live forever, not the reference. The latter one will be constrained by its scope.
```rust,editable
fn main() {
    {
        // Make a `string` literal and print it:
        let static_string = "I'm in read-only memory";
        println!("static_string: {}", static_string);

        // When `static_string` goes out of scope, the reference
        // can no longer be used, but the data remains in the binary.
    }

    println!("static_string reference remains alive: {}", static_string);
}
```

4. `&'static` can be coerced to a shorter lifetime.

**Example**
```rust,editable
// Make a constant with `'static` lifetime.
static NUM: i32 = 18;

// Returns a reference to `NUM` where its `'static`
// lifetime is coerced to that of the input argument.
fn coerce_static<'a>(_: &'a i32) -> &'a i32 {
    &NUM
}

fn main() {
    {
        // Make an integer to use for `coerce_static`:
        let lifetime_num = 9;

        // Coerce `NUM` to lifetime of `lifetime_num`:
        let coerced_static = coerce_static(&lifetime_num);

        println!("coerced_static: {}", coerced_static);
    }

    println!("NUM: {} stays accessible!", NUM);
}
```



##  T: 'static
As a trait bound, it means the type does not contain any non-static references. Eg. the receiver can hold on to the type for as long as they want and it will never become invalid until they drop it.


It's important to understand this means that any owned data always passes a `'static `lifetime bound, but a reference to that owned data generally does not.


5. 🌟🌟
```rust,editable
/* Make it work */
use std::fmt::Debug;

fn print_it<T: Debug + 'static>( input: T) {
    println!( "'static value passed in is: {:?}", input );
}

fn print_it1( input: impl Debug + 'static ) {
    println!( "'static value passed in is: {:?}", input );
}


fn print_it2<T: Debug + 'static>( input: &T) {
    println!( "'static value passed in is: {:?}", input );
}

fn main() {
    // i is owned and contains no references, thus it's 'static:
    let i = 5;
    print_it(i);

    // oops, &i only has the lifetime defined by the scope of
    // main(), so it's not 'static:
    print_it(&i);

    print_it1(&i);

    // but this one WORKS !
    print_it2(&i);
}
```


6. 🌟🌟🌟
```rust,editable
use std::fmt::Display;

fn main() {
  let mut string = "First".to_owned();

  string.push_str(string.to_uppercase().as_str());
  print_a(&string);
  print_b(&string);
  print_c(&string); // Compilation error
  print_d(&string); // Compilation error
  print_e(&string);
  print_f(&string);
  print_g(&string); // Compilation error
}

fn print_a<T: Display + 'static>(t: &T) {
  p
Download .txt
gitextract_vvz_1z8d/

├── .gitignore
├── .prettierignore
├── LICENSE
├── Readme.md
├── en/
│   ├── assets/
│   │   ├── CNAME
│   │   ├── custom3.js
│   │   ├── lang1.js
│   │   └── temp.md
│   ├── book.toml
│   ├── deploy.sh
│   ├── src/
│   │   ├── .gitignore
│   │   ├── SUMMARY.md
│   │   ├── about.md
│   │   ├── async/
│   │   │   ├── async-await.md
│   │   │   ├── future.md
│   │   │   ├── intro.md
│   │   │   ├── pin-unpin.md
│   │   │   └── stream.md
│   │   ├── basic-types/
│   │   │   ├── char-bool-unit.md
│   │   │   ├── functions.md
│   │   │   ├── intro.md
│   │   │   ├── numbers.md
│   │   │   └── statements-expressions.md
│   │   ├── circle-reference/
│   │   │   └── intro.md
│   │   ├── collections/
│   │   │   ├── hashmap.md
│   │   │   ├── intro.md
│   │   │   ├── string.md
│   │   │   └── vector.md
│   │   ├── comments-docs.md
│   │   ├── compound-types/
│   │   │   ├── array.md
│   │   │   ├── enum.md
│   │   │   ├── intro.md
│   │   │   ├── slice.md
│   │   │   ├── string.md
│   │   │   ├── struct.md
│   │   │   └── tuple.md
│   │   ├── crate-module/
│   │   │   ├── crate.md
│   │   │   ├── intro.md
│   │   │   ├── module.md
│   │   │   └── use-pub.md
│   │   ├── elegant-code-base.md
│   │   ├── errors.md
│   │   ├── fight-compiler/
│   │   │   ├── borrowing.md
│   │   │   └── intro.md
│   │   ├── flow-control.md
│   │   ├── formatted-output/
│   │   │   ├── debug-display.md
│   │   │   ├── formatting.md
│   │   │   ├── intro.md
│   │   │   └── println.md
│   │   ├── functional-programing/
│   │   │   ├── closure.md
│   │   │   ├── intro.md
│   │   │   └── iterator.md
│   │   ├── generics-traits/
│   │   │   ├── advanced-traits.md
│   │   │   ├── const-generics.md
│   │   │   ├── generics.md
│   │   │   ├── intro.md
│   │   │   ├── trait-object.md
│   │   │   └── traits.md
│   │   ├── global-variables.md
│   │   ├── lifetime/
│   │   │   ├── advance.md
│   │   │   ├── basic.md
│   │   │   ├── intro.md
│   │   │   └── static.md
│   │   ├── macro.md
│   │   ├── method.md
│   │   ├── newtype-sized.md
│   │   ├── ownership/
│   │   │   ├── borrowing.md
│   │   │   ├── intro.md
│   │   │   └── ownership.md
│   │   ├── pattern-match/
│   │   │   ├── intro.md
│   │   │   ├── match-iflet.md
│   │   │   └── patterns.md
│   │   ├── result-panic/
│   │   │   ├── intro.md
│   │   │   ├── panic.md
│   │   │   └── result.md
│   │   ├── self-referential.md
│   │   ├── smart-pointers/
│   │   │   ├── box.md
│   │   │   ├── cell-refcell.md
│   │   │   ├── deref.md
│   │   │   ├── drop.md
│   │   │   ├── intro.md
│   │   │   └── rc-arc.md
│   │   ├── std/
│   │   │   ├── String.md
│   │   │   └── intro.md
│   │   ├── tests/
│   │   │   ├── assertions.md
│   │   │   ├── benchmark.md
│   │   │   ├── intro.md
│   │   │   ├── unit-integration.md
│   │   │   └── write-tests.md
│   │   ├── threads/
│   │   │   ├── atomic.md
│   │   │   ├── basic-using.md
│   │   │   ├── intro.md
│   │   │   ├── message-passing.md
│   │   │   ├── send-sync.md
│   │   │   └── sync.md
│   │   ├── type-conversions/
│   │   │   ├── as.md
│   │   │   ├── from-into.md
│   │   │   ├── intro.md
│   │   │   └── others.md
│   │   ├── unsafe/
│   │   │   ├── inline-asm.md
│   │   │   └── intro.md
│   │   ├── variables.md
│   │   ├── weak.md
│   │   └── why-exercise.md
│   └── theme/
│       ├── index1.hbs
│       └── style1.css
├── practices/
│   ├── doc-comments/
│   │   ├── .gitignore
│   │   ├── Cargo.toml
│   │   ├── Readme.md
│   │   └── src/
│   │       ├── compute.rs
│   │       └── lib.rs
│   └── hello-package/
│       ├── .gitignore
│       ├── Cargo.toml
│       ├── Readme.md
│       └── src/
│           ├── back_of_house.rs
│           ├── front_of_house/
│           │   ├── hosting.rs
│           │   ├── mod.rs
│           │   └── serving.rs
│           ├── lib.rs
│           └── main.rs
├── scripts/
│   └── link_solution
├── solutions/
│   ├── basic-types/
│   │   ├── char-bool.md
│   │   ├── functions.md
│   │   ├── numbers.md
│   │   └── statements.md
│   ├── collections/
│   │   ├── Hashmap.md
│   │   ├── String.md
│   │   └── Vector.md
│   ├── compound-types/
│   │   ├── array.md
│   │   ├── enum.md
│   │   ├── slice.md
│   │   ├── string.md
│   │   ├── struct.md
│   │   └── tuple.md
│   ├── crate-module/
│   │   ├── crate.md
│   │   ├── module.md
│   │   └── use-pub.md
│   ├── fight-compiler/
│   │   └── borrowing.md
│   ├── flow-control.md
│   ├── formatted-output/
│   │   ├── debug-display.md
│   │   ├── formatting.md
│   │   └── println.md
│   ├── functional-programing/
│   │   ├── closure.md
│   │   └── iterator.md
│   ├── generics-traits/
│   │   ├── advanced-trait.md
│   │   ├── const-generics.md
│   │   ├── generics.md
│   │   ├── trait-object.md
│   │   └── traits.md
│   ├── lifetime/
│   │   ├── advance.md
│   │   ├── basic.md
│   │   └── static.md
│   ├── method.md
│   ├── newtype-sized.md
│   ├── ownership/
│   │   ├── borrowing.md
│   │   └── ownership.md
│   ├── pattern-match/
│   │   ├── match.md
│   │   └── patterns.md
│   ├── result-panic/
│   │   ├── panic.md
│   │   └── result.md
│   ├── type-conversions/
│   │   ├── as.md
│   │   ├── from-into.md
│   │   └── others.md
│   └── variables.md
└── zh-CN/
    ├── assets/
    │   ├── CNAME
    │   ├── custom3.js
    │   ├── lang1.js
    │   └── mini-redis/
    │       ├── .github/
    │       │   └── workflows/
    │       │       └── ci.yml
    │       ├── .gitignore
    │       ├── Cargo.toml
    │       ├── LICENSE
    │       ├── README.md
    │       ├── examples/
    │       │   ├── chat.rs
    │       │   ├── hello_world.rs
    │       │   ├── pub.rs
    │       │   └── sub.rs
    │       ├── src/
    │       │   ├── bin/
    │       │   │   ├── cli.rs
    │       │   │   └── server.rs
    │       │   ├── blocking_client.rs
    │       │   ├── buffer.rs
    │       │   ├── client.rs
    │       │   ├── cmd/
    │       │   │   ├── get.rs
    │       │   │   ├── mod.rs
    │       │   │   ├── publish.rs
    │       │   │   ├── set.rs
    │       │   │   ├── subscribe.rs
    │       │   │   └── unknown.rs
    │       │   ├── connection.rs
    │       │   ├── db.rs
    │       │   ├── frame.rs
    │       │   ├── lib.rs
    │       │   ├── parse.rs
    │       │   ├── server.rs
    │       │   └── shutdown.rs
    │       └── tests/
    │           ├── buffer.rs
    │           ├── client.rs
    │           └── server.rs
    ├── book.toml
    ├── deploy.sh
    ├── src/
    │   ├── SUMMARY.md
    │   ├── about.md
    │   ├── async/
    │   │   ├── async-await.md
    │   │   ├── future.md
    │   │   ├── intro.md
    │   │   ├── pin-unpin.md
    │   │   └── stream.md
    │   ├── basic-types/
    │   │   ├── char-bool-unit.md
    │   │   ├── functions.md
    │   │   ├── intro.md
    │   │   ├── numbers.md
    │   │   └── statements-expressions.md
    │   ├── circle-reference/
    │   │   └── intro.md
    │   ├── collections/
    │   │   ├── hashmap.md
    │   │   ├── intro.md
    │   │   ├── string.md
    │   │   └── vector.md
    │   ├── comments-docs.md
    │   ├── compound-types/
    │   │   ├── array.md
    │   │   ├── enum.md
    │   │   ├── intro.md
    │   │   ├── slice.md
    │   │   ├── string.md
    │   │   ├── struct.md
    │   │   └── tuple.md
    │   ├── crate-module/
    │   │   ├── crate.md
    │   │   ├── intro.md
    │   │   ├── module.md
    │   │   └── use-pub.md
    │   ├── elegant-code-base.md
    │   ├── errors.md
    │   ├── fight-compiler/
    │   │   ├── borrowing.md
    │   │   └── intro.md
    │   ├── flow-control.md
    │   ├── formatted-output/
    │   │   ├── debug-display.md
    │   │   ├── formatting.md
    │   │   ├── intro.md
    │   │   └── println.md
    │   ├── functional-programing/
    │   │   ├── closure.md
    │   │   ├── intro.md
    │   │   └── iterator.md
    │   ├── generics-traits/
    │   │   ├── advanced-traits.md
    │   │   ├── const-generics.md
    │   │   ├── generics.md
    │   │   ├── intro.md
    │   │   ├── trait-object.md
    │   │   └── traits.md
    │   ├── global-variables.md
    │   ├── lifetime/
    │   │   ├── advance.md
    │   │   ├── basic.md
    │   │   ├── intro.md
    │   │   └── static.md
    │   ├── macro.md
    │   ├── method.md
    │   ├── newtype-sized.md
    │   ├── ownership/
    │   │   ├── borrowing.md
    │   │   ├── intro.md
    │   │   └── ownership.md
    │   ├── pattern-match/
    │   │   ├── intro.md
    │   │   ├── match-iflet.md
    │   │   └── patterns.md
    │   ├── result-panic/
    │   │   ├── intro.md
    │   │   ├── panic.md
    │   │   └── result.md
    │   ├── self-referential.md
    │   ├── smart-pointers/
    │   │   ├── box.md
    │   │   ├── cell-refcell.md
    │   │   ├── deref.md
    │   │   ├── drop.md
    │   │   ├── intro.md
    │   │   └── rc-arc.md
    │   ├── std/
    │   │   ├── String.md
    │   │   └── intro.md
    │   ├── tests/
    │   │   ├── assertions.md
    │   │   ├── benchmark.md
    │   │   ├── intro.md
    │   │   ├── unit-integration.md
    │   │   └── write-tests.md
    │   ├── threads/
    │   │   ├── atomic.md
    │   │   ├── basic-using.md
    │   │   ├── intro.md
    │   │   ├── message-passing.md
    │   │   ├── send-sync.md
    │   │   └── sync.md
    │   ├── type-conversions/
    │   │   ├── as.md
    │   │   ├── from-into.md
    │   │   ├── intro.md
    │   │   └── others.md
    │   ├── unsafe/
    │   │   ├── inline-asm.md
    │   │   └── intro.md
    │   ├── variables.md
    │   ├── weak.md
    │   └── why-exercise.md
    └── theme/
        ├── index1.hbs
        └── style1.css
Download .txt
SYMBOL INDEX (195 symbols across 32 files)

FILE: practices/doc-comments/src/compute.rs
  function div (line 11) | pub fn div(a: i32, b: i32) -> i32 {
  function try_div (line 30) | pub fn try_div(a: i32, b: i32) -> Result<i32, String> {

FILE: practices/doc-comments/src/lib.rs
  function add_one (line 17) | pub fn add_one(x: i32) -> i32 {
  function add_two (line 34) | pub fn add_two(x: i32) -> i32 {
  function add_three (line 40) | pub fn add_three(x: i32) -> Option<i32> {
  function add_four (line 47) | pub fn add_four(x: i32) -> Option<i32> {
  type MySpecialFormatter (line 52) | struct MySpecialFormatter;

FILE: practices/hello-package/src/back_of_house.rs
  function fix_incorrect_order (line 2) | pub fn fix_incorrect_order() {
  function cook_order (line 7) | pub fn cook_order() {}

FILE: practices/hello-package/src/front_of_house/hosting.rs
  function add_to_waitlist (line 1) | pub fn add_to_waitlist() {}
  function seat_at_table (line 3) | pub fn seat_at_table() -> String {

FILE: practices/hello-package/src/front_of_house/serving.rs
  function take_order (line 1) | pub fn take_order() {}
  function serve_order (line 3) | pub fn serve_order() {}
  function take_payment (line 5) | pub fn take_payment() {}
  function complain (line 9) | fn complain() {}

FILE: practices/hello-package/src/lib.rs
  function eat_at_restaurant (line 6) | pub fn eat_at_restaurant() -> String {

FILE: practices/hello-package/src/main.rs
  function main (line 1) | fn main() {

FILE: zh-CN/assets/mini-redis/examples/chat.rs
  function main (line 2) | async fn main() {

FILE: zh-CN/assets/mini-redis/examples/hello_world.rs
  function main (line 19) | pub async fn main() -> Result<()> {

FILE: zh-CN/assets/mini-redis/examples/pub.rs
  function main (line 23) | async fn main() -> Result<()> {

FILE: zh-CN/assets/mini-redis/examples/sub.rs
  function main (line 23) | pub async fn main() -> Result<()> {

FILE: zh-CN/assets/mini-redis/src/bin/cli.rs
  type Cli (line 11) | struct Cli {
  type Command (line 23) | enum Command {
  function main (line 54) | async fn main() -> mini_redis::Result<()> {
  function duration_from_ms_str (line 101) | fn duration_from_ms_str(src: &str) -> Result<Duration, ParseIntError> {
  function bytes_from_str (line 106) | fn bytes_from_str(src: &str) -> Bytes {

FILE: zh-CN/assets/mini-redis/src/bin/server.rs
  function main (line 16) | pub async fn main() -> mini_redis::Result<()> {
  type Cli (line 34) | struct Cli {

FILE: zh-CN/assets/mini-redis/src/blocking_client.rs
  type BlockingClient (line 19) | pub struct BlockingClient {
    method get (line 101) | pub fn get(&mut self, key: &str) -> crate::Result<Option<Bytes>> {
    method set (line 130) | pub fn set(&mut self, key: &str, value: Bytes) -> crate::Result<()> {
    method set_expires (line 173) | pub fn set_expires(
    method publish (line 203) | pub fn publish(&mut self, channel: &str, message: Bytes) -> crate::Res...
    method subscribe (line 215) | pub fn subscribe(self, channels: Vec<String>) -> crate::Result<Blockin...
  type BlockingSubscriber (line 34) | pub struct BlockingSubscriber {
    method get_subscribed (line 226) | pub fn get_subscribed(&self) -> &[String] {
    method next_message (line 234) | pub fn next_message(&mut self) -> crate::Result<Option<Message>> {
    method into_iter (line 240) | pub fn into_iter(self) -> impl Iterator<Item = crate::Result<Message>> {
    method subscribe (line 248) | pub fn subscribe(&mut self, channels: &[String]) -> crate::Result<()> {
    method unsubscribe (line 253) | pub fn unsubscribe(&mut self, channels: &[String]) -> crate::Result<()> {
  type SubscriberIterator (line 44) | struct SubscriberIterator {
  function connect (line 72) | pub fn connect<T: ToSocketAddrs>(addr: T) -> crate::Result<BlockingClien...
  type Item (line 259) | type Item = crate::Result<Message>;
  method next (line 261) | fn next(&mut self) -> Option<crate::Result<Message>> {

FILE: zh-CN/assets/mini-redis/src/buffer.rs
  function buffer (line 24) | pub fn buffer(client: Client) -> Buffer {
  type Command (line 38) | enum Command {
  type Message (line 50) | type Message = (Command, oneshot::Sender<Result<Option<Bytes>>>);
  function run (line 54) | async fn run(mut client: Client, mut rx: Receiver<Message>) {
  type Buffer (line 74) | pub struct Buffer {
    method get (line 83) | pub async fn get(&mut self, key: &str) -> Result<Option<Bytes>> {
    method set (line 104) | pub async fn set(&mut self, key: &str, value: Bytes) -> Result<()> {

FILE: zh-CN/assets/mini-redis/src/client.rs
  type Client (line 23) | pub struct Client {
    method get (line 110) | pub async fn get(&mut self, key: &str) -> crate::Result<Option<Bytes>> {
    method set (line 159) | pub async fn set(&mut self, key: &str, value: Bytes) -> crate::Result<...
    method set_expires (line 207) | pub async fn set_expires(
    method set_cmd (line 220) | async fn set_cmd(&mut self, cmd: Set) -> crate::Result<()> {
    method publish (line 260) | pub async fn publish(&mut self, channel: &str, message: Bytes) -> crat...
    method subscribe (line 284) | pub async fn subscribe(mut self, channels: Vec<String>) -> crate::Resu...
    method subscribe_cmd (line 298) | async fn subscribe_cmd(&mut self, channels: &[String]) -> crate::Resul...
    method read_response (line 339) | async fn read_response(&mut self) -> crate::Result<Frame> {
  type Subscriber (line 39) | pub struct Subscriber {
    method get_subscribed (line 362) | pub fn get_subscribed(&self) -> &[String] {
    method next_message (line 370) | pub async fn next_message(&mut self) -> crate::Result<Option<Message>> {
    method into_stream (line 398) | pub fn into_stream(mut self) -> impl Stream<Item = crate::Result<Messa...
    method subscribe (line 412) | pub async fn subscribe(&mut self, channels: &[String]) -> crate::Resul...
    method unsubscribe (line 425) | pub async fn unsubscribe(&mut self, channels: &[String]) -> crate::Res...
  type Message (line 49) | pub struct Message {
  function connect (line 75) | pub async fn connect<T: ToSocketAddrs>(addr: T) -> crate::Result<Client> {

FILE: zh-CN/assets/mini-redis/src/cmd/get.rs
  type Get (line 12) | pub struct Get {
    method new (line 19) | pub fn new(key: impl ToString) -> Get {
    method key (line 26) | pub fn key(&self) -> &str {
    method parse_frames (line 50) | pub(crate) fn parse_frames(parse: &mut Parse) -> crate::Result<Get> {
    method apply (line 64) | pub(crate) async fn apply(self, db: &Db, dst: &mut Connection) -> crat...
    method into_frame (line 87) | pub(crate) fn into_frame(self) -> Frame {

FILE: zh-CN/assets/mini-redis/src/cmd/mod.rs
  type Command (line 22) | pub enum Command {
    method from_frame (line 40) | pub fn from_frame(frame: Frame) -> crate::Result<Command> {
    method apply (line 85) | pub(crate) async fn apply(
    method get_name (line 106) | pub(crate) fn get_name(&self) -> &str {

FILE: zh-CN/assets/mini-redis/src/cmd/publish.rs
  type Publish (line 13) | pub struct Publish {
    method new (line 23) | pub(crate) fn new(channel: impl ToString, message: Bytes) -> Publish {
    method parse_frames (line 50) | pub(crate) fn parse_frames(parse: &mut Parse) -> crate::Result<Publish> {
    method apply (line 67) | pub(crate) async fn apply(self, db: &Db, dst: &mut Connection) -> crat...
    method into_frame (line 93) | pub(crate) fn into_frame(self) -> Frame {

FILE: zh-CN/assets/mini-redis/src/cmd/set.rs
  type Set (line 21) | pub struct Set {
    method new (line 37) | pub fn new(key: impl ToString, value: Bytes, expire: Option<Duration>)...
    method key (line 46) | pub fn key(&self) -> &str {
    method value (line 51) | pub fn value(&self) -> &Bytes {
    method expire (line 56) | pub fn expire(&self) -> Option<Duration> {
    method parse_frames (line 80) | pub(crate) fn parse_frames(parse: &mut Parse) -> crate::Result<Set> {
    method apply (line 128) | pub(crate) async fn apply(self, db: &Db, dst: &mut Connection) -> crat...
    method into_frame (line 144) | pub(crate) fn into_frame(self) -> Frame {

FILE: zh-CN/assets/mini-redis/src/cmd/subscribe.rs
  type Subscribe (line 16) | pub struct Subscribe {
    method new (line 37) | pub(crate) fn new(channels: &[String]) -> Subscribe {
    method parse_frames (line 63) | pub(crate) fn parse_frames(parse: &mut Parse) -> crate::Result<Subscri...
    method apply (line 102) | pub(crate) async fn apply(
    method into_frame (line 162) | pub(crate) fn into_frame(self) -> Frame {
  type Unsubscribe (line 25) | pub struct Unsubscribe {
    method new (line 285) | pub(crate) fn new(channels: &[String]) -> Unsubscribe {
    method parse_frames (line 311) | pub(crate) fn parse_frames(parse: &mut Parse) -> Result<Unsubscribe, P...
    method into_frame (line 341) | pub(crate) fn into_frame(self) -> Frame {
  type Messages (line 33) | type Messages = Pin<Box<dyn Stream<Item = Bytes> + Send>>;
  function subscribe_to_channel (line 172) | async fn subscribe_to_channel(
  function handle_command (line 207) | async fn handle_command(
  function make_subscribe_frame (line 256) | fn make_subscribe_frame(channel_name: String, num_subs: usize) -> Frame {
  function make_unsubscribe_frame (line 265) | fn make_unsubscribe_frame(channel_name: String, num_subs: usize) -> Frame {
  function make_message_frame (line 275) | fn make_message_frame(channel_name: String, msg: Bytes) -> Frame {

FILE: zh-CN/assets/mini-redis/src/cmd/unknown.rs
  type Unknown (line 7) | pub struct Unknown {
    method new (line 14) | pub(crate) fn new(key: impl ToString) -> Unknown {
    method get_name (line 21) | pub(crate) fn get_name(&self) -> &str {
    method apply (line 29) | pub(crate) async fn apply(self, dst: &mut Connection) -> crate::Result...

FILE: zh-CN/assets/mini-redis/src/connection.rs
  type Connection (line 21) | pub struct Connection {
    method new (line 34) | pub fn new(socket: TcpStream) -> Connection {
    method read_frame (line 56) | pub async fn read_frame(&mut self) -> crate::Result<Option<Frame>> {
    method parse_frame (line 88) | fn parse_frame(&mut self) -> crate::Result<Option<Frame>> {
    method write_frame (line 157) | pub async fn write_frame(&mut self, frame: &Frame) -> io::Result<()> {
    method write_value (line 185) | async fn write_value(&mut self, frame: &Frame) -> io::Result<()> {
    method write_decimal (line 223) | async fn write_decimal(&mut self, val: u64) -> io::Result<()> {

FILE: zh-CN/assets/mini-redis/src/db.rs
  type DbDropGuard (line 13) | pub(crate) struct DbDropGuard {
    method new (line 109) | pub(crate) fn new() -> DbDropGuard {
    method db (line 115) | pub(crate) fn db(&self) -> Db {
  type Db (line 32) | pub(crate) struct Db {
    method new (line 130) | pub(crate) fn new() -> Db {
    method get (line 153) | pub(crate) fn get(&self, key: &str) -> Option<Bytes> {
    method set (line 166) | pub(crate) fn set(&self, key: String, value: Bytes, expire: Option<Dur...
    method subscribe (line 234) | pub(crate) fn subscribe(&self, key: String) -> broadcast::Receiver<Byt...
    method publish (line 265) | pub(crate) fn publish(&self, key: &str, value: Bytes) -> usize {
    method shutdown_purge_task (line 282) | fn shutdown_purge_task(&self) {
  type Shared (line 39) | struct Shared {
    method purge_expired_keys (line 299) | fn purge_expired_keys(&self) -> Option<Instant> {
    method is_shutdown (line 337) | fn is_shutdown(&self) -> bool {
  type State (line 61) | struct State {
    method next_expiration (line 343) | fn next_expiration(&self) -> Option<Instant> {
  type Entry (line 94) | struct Entry {
  method drop (line 121) | fn drop(&mut self) {
  function purge_expired_tasks (line 355) | async fn purge_expired_tasks(shared: Arc<Shared>) {

FILE: zh-CN/assets/mini-redis/src/frame.rs
  type Frame (line 13) | pub enum Frame {
    method array (line 33) | pub(crate) fn array() -> Frame {
    method push_bulk (line 42) | pub(crate) fn push_bulk(&mut self, bytes: Bytes) {
    method push_int (line 56) | pub(crate) fn push_int(&mut self, value: u64) {
    method check (line 66) | pub fn check(src: &mut Cursor<&[u8]>) -> Result<(), Error> {
    method parse (line 106) | pub fn parse(src: &mut Cursor<&[u8]>) -> Result<Frame, Error> {
    method to_error (line 171) | pub(crate) fn to_error(&self) -> crate::Error {
    method eq (line 177) | fn eq(&self, other: &&str) -> bool {
    method fmt (line 187) | fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
  type Error (line 23) | pub enum Error {
    method from (line 268) | fn from(src: String) -> Error {
    method from (line 274) | fn from(src: &str) -> Error {
    method from (line 280) | fn from(_src: FromUtf8Error) -> Error {
    method from (line 286) | fn from(_src: TryFromIntError) -> Error {
    method fmt (line 294) | fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
  function peek_u8 (line 213) | fn peek_u8(src: &mut Cursor<&[u8]>) -> Result<u8, Error> {
  function get_u8 (line 221) | fn get_u8(src: &mut Cursor<&[u8]>) -> Result<u8, Error> {
  function skip (line 229) | fn skip(src: &mut Cursor<&[u8]>, n: usize) -> Result<(), Error> {
  function get_decimal (line 239) | fn get_decimal(src: &mut Cursor<&[u8]>) -> Result<u64, Error> {
  function get_line (line 248) | fn get_line<'a>(src: &mut Cursor<&'a [u8]>) -> Result<&'a [u8], Error> {

FILE: zh-CN/assets/mini-redis/src/lib.rs
  constant DEFAULT_PORT (line 58) | pub const DEFAULT_PORT: &str = "6379";
  type Error (line 71) | pub type Error = Box<dyn std::error::Error + Send + Sync>;
  type Result (line 76) | pub type Result<T> = std::result::Result<T, Error>;

FILE: zh-CN/assets/mini-redis/src/parse.rs
  type Parse (line 13) | pub(crate) struct Parse {
    method new (line 36) | pub(crate) fn new(frame: Frame) -> Result<Parse, ParseError> {
    method next (line 49) | fn next(&mut self) -> Result<Frame, ParseError> {
    method next_string (line 59) | pub(crate) fn next_string(&mut self) -> Result<String, ParseError> {
    method next_bytes (line 82) | pub(crate) fn next_bytes(&mut self) -> Result<Bytes, ParseError> {
    method next_int (line 105) | pub(crate) fn next_int(&mut self) -> Result<u64, ParseError> {
    method finish (line 122) | pub(crate) fn finish(&mut self) -> Result<(), ParseError> {
  type ParseError (line 23) | pub(crate) enum ParseError {
    method from (line 132) | fn from(src: String) -> ParseError {
    method from (line 138) | fn from(src: &str) -> ParseError {
    method fmt (line 144) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {

FILE: zh-CN/assets/mini-redis/src/server.rs
  type Listener (line 18) | struct Listener {
    method run (line 227) | async fn run(&mut self) -> crate::Result<()> {
    method accept (line 291) | async fn accept(&mut self) -> crate::Result<TcpStream> {
  type Handler (line 70) | struct Handler {
    method run (line 331) | async fn run(&mut self) -> crate::Result<()> {
  constant MAX_CONNECTIONS (line 120) | const MAX_CONNECTIONS: usize = 250;
  function run (line 131) | pub async fn run(listener: TcpListener, shutdown: impl Future) {
  method drop (line 386) | fn drop(&mut self) {

FILE: zh-CN/assets/mini-redis/src/shutdown.rs
  type Shutdown (line 13) | pub(crate) struct Shutdown {
    method new (line 23) | pub(crate) fn new(notify: broadcast::Receiver<()>) -> Shutdown {
    method is_shutdown (line 31) | pub(crate) fn is_shutdown(&self) -> bool {
    method recv (line 36) | pub(crate) async fn recv(&mut self) {

FILE: zh-CN/assets/mini-redis/tests/buffer.rs
  function pool_key_value_get_set (line 11) | async fn pool_key_value_get_set() {
  function start_server (line 23) | async fn start_server() -> (SocketAddr, JoinHandle<()>) {

FILE: zh-CN/assets/mini-redis/tests/client.rs
  function key_value_get_set (line 10) | async fn key_value_get_set() {
  function receive_message_subscribed_channel (line 23) | async fn receive_message_subscribed_channel() {
  function receive_message_multiple_subscribed_channels (line 41) | async fn receive_message_multiple_subscribed_channels() {
  function unsubscribes_from_channels (line 72) | async fn unsubscribes_from_channels() {
  function start_server (line 85) | async fn start_server() -> (SocketAddr, JoinHandle<()>) {

FILE: zh-CN/assets/mini-redis/tests/server.rs
  function key_value_get_set (line 13) | async fn key_value_get_set() {
  function key_value_timeout (line 68) | async fn key_value_timeout() {
  function pub_sub (line 123) | async fn pub_sub() {
  function manage_subscription (line 246) | async fn manage_subscription() {
  function send_error_unknown_command (line 337) | async fn send_error_unknown_command() {
  function send_error_get_set_after_subscribe (line 359) | async fn send_error_get_set_after_subscribe() {
  function start_server (line 400) | async fn start_server() -> SocketAddr {
Condensed preview — 294 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (795K chars).
[
  {
    "path": ".gitignore",
    "chars": 32,
    "preview": "en/book\nzh-CN/book\n**/.DS_Store\n"
  },
  {
    "path": ".prettierignore",
    "chars": 4,
    "preview": "*.md"
  },
  {
    "path": "LICENSE",
    "chars": 18646,
    "preview": "Attribution 4.0 International\n\n=======================================================================\n\nCreative Commons"
  },
  {
    "path": "Readme.md",
    "chars": 4549,
    "preview": "<div align=\"center\">\n    <img src=\"https://github.com/sunface/rust-by-practice/blob/master/en/assets/header.jpg?raw=true"
  },
  {
    "path": "en/assets/CNAME",
    "chars": 18,
    "preview": "practice.course.rs"
  },
  {
    "path": "en/assets/custom3.js",
    "chars": 5574,
    "preview": "var initAll = function () {\n    var path = window.location.pathname;\n    if (path.endsWith(\"/print.html\")) {\n        ret"
  },
  {
    "path": "en/assets/lang1.js",
    "chars": 862,
    "preview": "(function () {\n  var path = window.location.pathname;\n  var link = \"https://practice.course.rs\" + path;\n  var word = \"En"
  },
  {
    "path": "en/assets/temp.md",
    "chars": 1046,
    "preview": "# 字符、布尔、单元类型\n\n### 字符\n🌟\n```rust\n\nuse std::mem::size_of_val;\nfn main() {\n    let c1 = 'a';\n    assert_eq!(size_of_val(&c1)"
  },
  {
    "path": "en/book.toml",
    "chars": 587,
    "preview": "[book]\ntitle = \"Rust By Practice\"\ndescription = \"Learn Rust with Example, Exercise and real Practice, written with ❤️ by"
  },
  {
    "path": "en/deploy.sh",
    "chars": 454,
    "preview": "## this script deploys the static website of course.rs to github pages\n\n## build static website for book\nmdbook build\n##"
  },
  {
    "path": "en/src/.gitignore",
    "chars": 4,
    "preview": "book"
  },
  {
    "path": "en/src/SUMMARY.md",
    "chars": 3834,
    "preview": "# Summary\n\n- [Rust By Practice](why-exercise.md)\n- [Small projects with Elegant code](elegant-code-base.md)\n- [Variables"
  },
  {
    "path": "en/src/about.md",
    "chars": 19,
    "preview": "# Rust By Practice\n"
  },
  {
    "path": "en/src/async/async-await.md",
    "chars": 19,
    "preview": "# async and await!\n"
  },
  {
    "path": "en/src/async/future.md",
    "chars": 9,
    "preview": "# Future\n"
  },
  {
    "path": "en/src/async/intro.md",
    "chars": 14,
    "preview": "# Async/Await\n"
  },
  {
    "path": "en/src/async/pin-unpin.md",
    "chars": 16,
    "preview": "# Pin and Unpin\n"
  },
  {
    "path": "en/src/async/stream.md",
    "chars": 9,
    "preview": "# Stream\n"
  },
  {
    "path": "en/src/basic-types/char-bool-unit.md",
    "chars": 1480,
    "preview": "# Char, Bool and Unit\n\n### Char\n1. 🌟\n```rust,editable\n\n// Make it work\nuse std::mem::size_of_val;\nfn main() {\n    let c1"
  },
  {
    "path": "en/src/basic-types/functions.md",
    "chars": 1767,
    "preview": "# Functions\n1. 🌟🌟🌟\n```rust,editable\n\nfn main() {\n    // Don't modify the following two lines!\n    let (x, y) = (1, 2);\n "
  },
  {
    "path": "en/src/basic-types/intro.md",
    "chars": 199,
    "preview": "# Basic Types\nLearning resources: \n- English: [Rust Book 3.2 and 3.3](https://doc.rust-lang.org/book/ch03-02-data-types."
  },
  {
    "path": "en/src/basic-types/numbers.md",
    "chars": 3430,
    "preview": "# Numbers\n\n### Integer\n\n1. 🌟 \n\n> Tips: If we don't explicitly assign a type to a variable, then the compiler will infer "
  },
  {
    "path": "en/src/basic-types/statements-expressions.md",
    "chars": 1080,
    "preview": "# Statements and Expressions\n\n### Examples\n```rust,editable\nfn main() {\n    let x = 5u32;\n\n    let y = {\n        let x_s"
  },
  {
    "path": "en/src/circle-reference/intro.md",
    "chars": 40,
    "preview": "# Circle reference and Self referential\n"
  },
  {
    "path": "en/src/collections/hashmap.md",
    "chars": 7339,
    "preview": "# HashMap\nWhere vectors store values by an integer index, HashMaps store values by key. It is a hash map implemented wit"
  },
  {
    "path": "en/src/collections/intro.md",
    "chars": 212,
    "preview": "# Collection Types\nLearning resources: \n- English: [Rust Book Chapter 8](https://doc.rust-lang.org/book/ch08-00-common-c"
  },
  {
    "path": "en/src/collections/string.md",
    "chars": 5389,
    "preview": "# String\n`std::string::String` is a UTF-8 encoded, growable string. It is the most common string type we used in daily d"
  },
  {
    "path": "en/src/collections/vector.md",
    "chars": 5563,
    "preview": "# Vector\nVectors are resizable arrays. Like slices, their size is not known at compile time, but they can grow or shrink"
  },
  {
    "path": "en/src/comments-docs.md",
    "chars": 6919,
    "preview": "# Comments and Docs\nEvery program requires comments:\n\n\n## Comments\n- Regular comments which are ignored by the compiler:"
  },
  {
    "path": "en/src/compound-types/array.md",
    "chars": 2247,
    "preview": "# Array\nThe type of array is `[T; Length]`, as you can see, array's length is part of their type signature. So their len"
  },
  {
    "path": "en/src/compound-types/enum.md",
    "chars": 4825,
    "preview": "# Enum\n1. 🌟🌟 Enums can be created with explicit discriminator.\n\n```rust,editable\n\n// Fix the errors\nenum Number {\n    Ze"
  },
  {
    "path": "en/src/compound-types/intro.md",
    "chars": 210,
    "preview": "# Compound Types\nLearning resources: \n- English: [Rust Book 4.3, 5.1, 6.1, 8.2](https://doc.rust-lang.org/book/ch04-03-s"
  },
  {
    "path": "en/src/compound-types/slice.md",
    "chars": 2670,
    "preview": "# Slice\nSlices are similar to arrays, but their length is not known at compile time, so you can't use slice directly.\n\n1"
  },
  {
    "path": "en/src/compound-types/string.md",
    "chars": 7123,
    "preview": "# String\nThe type of string literal `\"hello, world\"` is `&str`, e.g `let s: &str = \"hello, world\"`.\n\n\n### Str and &str\n1"
  },
  {
    "path": "en/src/compound-types/struct.md",
    "chars": 5351,
    "preview": "# Struct\n\n### The types of structs\n1. 🌟 We must specify concrete values for each of the fields in struct.\n```rust,editab"
  },
  {
    "path": "en/src/compound-types/tuple.md",
    "chars": 1930,
    "preview": "# Tuple\n1. 🌟 Elements in a tuple can have different types. Tuple's type signature is `(T1, T2, ...)`, where `T1`, `T2` a"
  },
  {
    "path": "en/src/crate-module/crate.md",
    "chars": 2881,
    "preview": "# Package and Crate\nA package is a project which you create with Cargo (in most cases), so it contains a `Cargo.toml` fi"
  },
  {
    "path": "en/src/crate-module/intro.md",
    "chars": 253,
    "preview": "# Crate and module\nLearning resources: \n- English: [Rust Book Chapter 7](https://doc.rust-lang.org/book/ch07-00-managing"
  },
  {
    "path": "en/src/crate-module/module.md",
    "chars": 4199,
    "preview": "# Module\nModules let us organize the code within a crate into groups for readability and ease of reuse. Module also cont"
  },
  {
    "path": "en/src/crate-module/use-pub.md",
    "chars": 1795,
    "preview": "# Use and pub\n1. 🌟 We can bring two types of the same name into the same scope with use, but you need `as` keyword.\n\n```"
  },
  {
    "path": "en/src/elegant-code-base.md",
    "chars": 2817,
    "preview": "# Small projects with Elegant code base\nFollowing questions come up weekly in online Rust discussions: \n\n- I just finish"
  },
  {
    "path": "en/src/errors.md",
    "chars": 9,
    "preview": "# Errors\n"
  },
  {
    "path": "en/src/fight-compiler/borrowing.md",
    "chars": 626,
    "preview": "# Borrowing\n\n1. 🌟🌟\n```rust,editable\n// FIX the error without removing any code line\nstruct test {\n    list: Vec<i32>,\n  "
  },
  {
    "path": "en/src/fight-compiler/intro.md",
    "chars": 231,
    "preview": "# Fighting with Compiler\nFighting with compiler is very common in our daily coding, especially for those unfamiliar with"
  },
  {
    "path": "en/src/flow-control.md",
    "chars": 4737,
    "preview": "# Flow control\n\n### If/else\n1. 🌟 \n```rust,editable\n\n// Fill in the blanks\nfn main() {\n    let n = 5;\n\n    if n < 0 {\n   "
  },
  {
    "path": "en/src/formatted-output/debug-display.md",
    "chars": 4264,
    "preview": "# Debug and Display\nAll types which want to be printable must implement the `std::fmt` formatting trait: `std::fmt::Debu"
  },
  {
    "path": "en/src/formatted-output/formatting.md",
    "chars": 4162,
    "preview": "# Formatting\n\n## Positional arguments\n\n1.🌟🌟\n```rust,editable\n/* Fill in the blanks */\nfn main() {\n    println!(\"{0}, thi"
  },
  {
    "path": "en/src/formatted-output/intro.md",
    "chars": 2569,
    "preview": "# Formatted output\n\n```rust,editable,ignore,mdbook-runnable\nfn main() {\n    // In general, the `{}` will be automaticall"
  },
  {
    "path": "en/src/formatted-output/println.md",
    "chars": 1139,
    "preview": "# println! and format!\nPrinting is handled by a series of [`macros`][macros] defined in [`std::fmt`][fmt]\nSome of which "
  },
  {
    "path": "en/src/functional-programing/closure.md",
    "chars": 9367,
    "preview": "# Closure\nClosures can capture the enclosing environments. For example we can capture the `x` variable :\n```rust\nfn main"
  },
  {
    "path": "en/src/functional-programing/intro.md",
    "chars": 231,
    "preview": "# Functional programing\nLearning resources: \n- English: [Rust Book 13](https://doc.rust-lang.org/book/ch13-00-functional"
  },
  {
    "path": "en/src/functional-programing/iterator.md",
    "chars": 7837,
    "preview": "# Iterator\nThe iterator pattern allows us to perform some tasks on a sequence of items in turn. An iterator is responsib"
  },
  {
    "path": "en/src/generics-traits/advanced-traits.md",
    "chars": 7184,
    "preview": "# Advance Traits\n\n## Associated types\nThe use of \"Associated types\" improves the overall readability of code by moving i"
  },
  {
    "path": "en/src/generics-traits/const-generics.md",
    "chars": 4493,
    "preview": "# Const Generics\nConst generics are generic arguments that range over constant values, rather than types or lifetimes. T"
  },
  {
    "path": "en/src/generics-traits/generics.md",
    "chars": 2791,
    "preview": "# Generics\n\n### Functions\n1. 🌟🌟🌟\n```rust,editable\n\n// Fill in the blanks to make it work\nstruct A;          // Concrete "
  },
  {
    "path": "en/src/generics-traits/intro.md",
    "chars": 201,
    "preview": "# Generics and Traits\nLearning resources: \n- English: [Rust Book 10.1, 10.2](https://doc.rust-lang.org/book/ch10-00-gene"
  },
  {
    "path": "en/src/generics-traits/trait-object.md",
    "chars": 5538,
    "preview": "# Trait Object\nIn [traits chapter](https://practice.rs/generics-traits/traits.html#returning-types-that-implement-traits"
  },
  {
    "path": "en/src/generics-traits/traits.md",
    "chars": 11032,
    "preview": "# Traits\nA trait tells the Rust compiler about functionality a particular type has and can share with other types. We ca"
  },
  {
    "path": "en/src/global-variables.md",
    "chars": 19,
    "preview": "# Global variables\n"
  },
  {
    "path": "en/src/lifetime/advance.md",
    "chars": 6435,
    "preview": "# Advance lifetime\n\n## Trait Bounds\nJust like generic types can be bounded, lifetimes can also be bounded as below:\n- `T"
  },
  {
    "path": "en/src/lifetime/basic.md",
    "chars": 9086,
    "preview": "## Lifetime\nThe compiler uses lifetime to ensure all borrows are valid. Typically, a variable's lifetime begins when it "
  },
  {
    "path": "en/src/lifetime/intro.md",
    "chars": 195,
    "preview": "# Lifetime\nLearning resources: \n- English: [Rust Book 10.3](https://doc.rust-lang.org/book/ch10-03-lifetime-syntax.html)"
  },
  {
    "path": "en/src/lifetime/static.md",
    "chars": 4608,
    "preview": "# &'static and T: 'static\n`'static` is a reserved lifetime name, you might have encountered it several times:\n```rust\n//"
  },
  {
    "path": "en/src/macro.md",
    "chars": 8,
    "preview": "# macro\n"
  },
  {
    "path": "en/src/method.md",
    "chars": 6957,
    "preview": "# Associated functions & Methods\n\n## Examples\n```rust,editable\nstruct Point {\n    x: f64,\n    y: f64,\n}\n\n// Implementati"
  },
  {
    "path": "en/src/newtype-sized.md",
    "chars": 4396,
    "preview": "# newtype and Sized\n\n## Newtype\nThe orphan rule tells us that we are allowed to implement a trait on a type as long as e"
  },
  {
    "path": "en/src/ownership/borrowing.md",
    "chars": 2935,
    "preview": "# Reference and Borrowing\n\n### Reference\n1. 🌟\n```rust,editable\n\nfn main() {\n   let x = 5;\n   // Fill the blank\n   let p "
  },
  {
    "path": "en/src/ownership/intro.md",
    "chars": 222,
    "preview": "# Ownership and Borrowing\nLearning resources: \n- English: [Rust Book 4.1-4.4](https://doc.rust-lang.org/book/ch04-00-und"
  },
  {
    "path": "en/src/ownership/ownership.md",
    "chars": 3384,
    "preview": "# Ownership\n\n1. 🌟🌟 \n```rust,editable\n\nfn main() {\n    // Use as many approaches as you can to make it work\n    let x = S"
  },
  {
    "path": "en/src/pattern-match/intro.md",
    "chars": 195,
    "preview": "# Pattern Match\nLearning resources: \n- English: [Rust Book 18](https://doc.rust-lang.org/book/ch18-00-patterns.html)\n- 简"
  },
  {
    "path": "en/src/pattern-match/match-iflet.md",
    "chars": 3810,
    "preview": "# Match, if let\n\n### Match\n1. 🌟🌟\n```rust,editable\n\n// Fill the blanks\nenum Direction {\n    East,\n    West,\n    North,\n  "
  },
  {
    "path": "en/src/pattern-match/patterns.md",
    "chars": 2984,
    "preview": "# Patterns\n\n1. 🌟🌟 Use `|` to match several values, use `..=` to match an inclusive range.\n```rust,editable\n\nfn main() {}"
  },
  {
    "path": "en/src/result-panic/intro.md",
    "chars": 212,
    "preview": "# Result and panic\nLearning resources: \n- English: [Rust Book 9.1, 9.2](https://doc.rust-lang.org/book/ch09-00-error-han"
  },
  {
    "path": "en/src/result-panic/panic.md",
    "chars": 3848,
    "preview": "# panic!\nThe simplest error handling mechanism is to use `panic`. It just prints an error message and starts unwinding t"
  },
  {
    "path": "en/src/result-panic/result.md",
    "chars": 5392,
    "preview": "# result and ?\n`Result<T>` is an enum to describe possible errors. It has two variants: \n\n- `Ok(T)`: A value T was found"
  },
  {
    "path": "en/src/self-referential.md",
    "chars": 19,
    "preview": "# Self referential\n"
  },
  {
    "path": "en/src/smart-pointers/box.md",
    "chars": 780,
    "preview": "# Box\n\n1. 🌟\n```rust,editable\n// Make it work\nfn main() {\n    // Create a new box `b` that contains the integer 5\n    ass"
  },
  {
    "path": "en/src/smart-pointers/cell-refcell.md",
    "chars": 19,
    "preview": "# Cell and RefCell\n"
  },
  {
    "path": "en/src/smart-pointers/deref.md",
    "chars": 8,
    "preview": "# Deref\n"
  },
  {
    "path": "en/src/smart-pointers/drop.md",
    "chars": 7,
    "preview": "# Drop\n"
  },
  {
    "path": "en/src/smart-pointers/intro.md",
    "chars": 94,
    "preview": "# Smart pointers\n\n<!-- https://github.com/marvinguo/rust-best-practices/tree/main/examples -->"
  },
  {
    "path": "en/src/smart-pointers/rc-arc.md",
    "chars": 13,
    "preview": "# Rc and Arc\n"
  },
  {
    "path": "en/src/std/String.md",
    "chars": 14,
    "preview": "# String TODO\n"
  },
  {
    "path": "en/src/std/intro.md",
    "chars": 21,
    "preview": "# Stand Library todo\n"
  },
  {
    "path": "en/src/tests/assertions.md",
    "chars": 13,
    "preview": "# Assertions\n"
  },
  {
    "path": "en/src/tests/benchmark.md",
    "chars": 79,
    "preview": "# Benchmark\n\nhttps://doc.rust-lang.org/unstable-book/library-features/test.html"
  },
  {
    "path": "en/src/tests/intro.md",
    "chars": 8,
    "preview": "# Tests\n"
  },
  {
    "path": "en/src/tests/unit-integration.md",
    "chars": 23,
    "preview": "# Unit and Integration\n"
  },
  {
    "path": "en/src/tests/write-tests.md",
    "chars": 14,
    "preview": "# Write Tests\n"
  },
  {
    "path": "en/src/threads/atomic.md",
    "chars": 9,
    "preview": "# Atomic\n"
  },
  {
    "path": "en/src/threads/basic-using.md",
    "chars": 14,
    "preview": "# Basic using\n"
  },
  {
    "path": "en/src/threads/intro.md",
    "chars": 10,
    "preview": "# Threads\n"
  },
  {
    "path": "en/src/threads/message-passing.md",
    "chars": 18,
    "preview": "# Message passing\n"
  },
  {
    "path": "en/src/threads/send-sync.md",
    "chars": 16,
    "preview": "# Send and Sync\n"
  },
  {
    "path": "en/src/threads/sync.md",
    "chars": 7,
    "preview": "# Sync\n"
  },
  {
    "path": "en/src/type-conversions/as.md",
    "chars": 3221,
    "preview": "# Convert by `as`\nRust provides no implicit type conversion(coercion) between primitive types. But explicit type convers"
  },
  {
    "path": "en/src/type-conversions/from-into.md",
    "chars": 4797,
    "preview": "# From/Into\nThe `From` trait allows for a type to define how to create itself from another type, hence providing a very "
  },
  {
    "path": "en/src/type-conversions/intro.md",
    "chars": 153,
    "preview": "# Type Conversion\nLearning resources: \n- English: [Standary library](https://std.rs)\n- 简体中文: [Rust语言圣经 - 所有权与借用](https:/"
  },
  {
    "path": "en/src/type-conversions/others.md",
    "chars": 5482,
    "preview": "# Others\n\n### Convert any type to String\nTo convert any type to `String`, you can simply use the `ToString` trait for th"
  },
  {
    "path": "en/src/unsafe/inline-asm.md",
    "chars": 18244,
    "preview": "# Inline assembly\n\nRust provides support for inline assembly via the `asm!` macro.\nIt can be used to embed handwritten a"
  },
  {
    "path": "en/src/unsafe/intro.md",
    "chars": 14,
    "preview": "# Unsafe todo\n"
  },
  {
    "path": "en/src/variables.md",
    "chars": 3050,
    "preview": "# Variables\n\n### Binding and mutability\n1. 🌟 A variable can be used only if it has been initialized.\n```rust,editable\n\n/"
  },
  {
    "path": "en/src/weak.md",
    "chars": 28,
    "preview": "# Weak and Circle reference\n"
  },
  {
    "path": "en/src/why-exercise.md",
    "chars": 2042,
    "preview": "<div align=\"center\">\n    <img  src=\"https://github.com/sunface/rust-by-practice/blob/master/en/assets/header.jpg?raw=tru"
  },
  {
    "path": "en/theme/index1.hbs",
    "chars": 15789,
    "preview": "<!DOCTYPE HTML>\n<html lang=\"{{ language }}\" class=\"{{ default_theme }}\" dir=\"{{ text_direction }}\">\n    <head>\n        <"
  },
  {
    "path": "en/theme/style1.css",
    "chars": 1824,
    "preview": "@media only screen and (max-width:1080px) {\n    .sidetoc {\n        display: none !important;\n    }\n}\n\n@media only screen"
  },
  {
    "path": "practices/doc-comments/.gitignore",
    "chars": 19,
    "preview": "/target\nCargo.lock\n"
  },
  {
    "path": "practices/doc-comments/Cargo.toml",
    "chars": 181,
    "preview": "[package]\nname = \"doc-comments\"\nversion = \"0.1.0\"\nedition = \"2021\"\n\n# See more keys and their definitions at https://doc"
  },
  {
    "path": "practices/doc-comments/Readme.md",
    "chars": 112,
    "preview": "## Doc comments\nA practice project used in [Comments and Docs](https://practice.rs/comments-docs.html) chapter.\n"
  },
  {
    "path": "practices/doc-comments/src/compute.rs",
    "chars": 740,
    "preview": "//! Do some complicated arithmetic that you can't do by yourself\n\n/// # Panics\n///\n/// The function panics if the second"
  },
  {
    "path": "practices/doc-comments/src/lib.rs",
    "chars": 865,
    "preview": "//! # Doc comments\n//! \n//! A library for showing how to use doc comments\n\npub mod compute;\n\n/// Add one to the given va"
  },
  {
    "path": "practices/hello-package/.gitignore",
    "chars": 19,
    "preview": "/target\nCargo.lock\n"
  },
  {
    "path": "practices/hello-package/Cargo.toml",
    "chars": 182,
    "preview": "[package]\nname = \"hello-package\"\nversion = \"0.1.0\"\nedition = \"2021\"\n\n# See more keys and their definitions at https://do"
  },
  {
    "path": "practices/hello-package/Readme.md",
    "chars": 465,
    "preview": "## Hello Package\nA practice project used in [Crate and Module](https://practice.rs/crate-module/crate.html) chapter.\n\nTh"
  },
  {
    "path": "practices/hello-package/src/back_of_house.rs",
    "chars": 145,
    "preview": "use crate::front_of_house;\npub fn fix_incorrect_order() {\n    cook_order();\n    front_of_house::serving::serve_order();\n"
  },
  {
    "path": "practices/hello-package/src/front_of_house/hosting.rs",
    "chars": 103,
    "preview": "pub fn add_to_waitlist() {}\n\npub fn seat_at_table() -> String {\n    String::from(\"sit down please\")\n}\n\n"
  },
  {
    "path": "practices/hello-package/src/front_of_house/mod.rs",
    "chars": 33,
    "preview": "pub mod hosting;\npub mod serving;"
  },
  {
    "path": "practices/hello-package/src/front_of_house/serving.rs",
    "chars": 193,
    "preview": "pub fn take_order() {}\n\npub fn serve_order() {}\n\npub fn take_payment() {}\n\n// Maybe you don't want the guest hearing the"
  },
  {
    "path": "practices/hello-package/src/lib.rs",
    "chars": 242,
    "preview": "mod front_of_house;\nmod back_of_house;\n\npub use crate::front_of_house::hosting;\n\npub fn eat_at_restaurant() -> String {\n"
  },
  {
    "path": "practices/hello-package/src/main.rs",
    "chars": 157,
    "preview": "fn main() {\n    assert_eq!(hello_package::hosting::seat_at_table(), \"sit down please\");\n    assert_eq!(hello_package::ea"
  },
  {
    "path": "scripts/link_solution",
    "chars": 1962,
    "preview": "#!/usr/bin/env bash\n#\n# Function:\n#   1. Link solution page to each practice page where there is no solution link\n#   2."
  },
  {
    "path": "solutions/basic-types/char-bool.md",
    "chars": 962,
    "preview": "1.\n\n```rust\nuse std::mem::size_of_val;\n\nfn main() {\n    let c1 = 'a';\n    assert_eq!(size_of_val(&c1), 4);\n\n    let c2 ="
  },
  {
    "path": "solutions/basic-types/functions.md",
    "chars": 1919,
    "preview": "1.\n\n```rust\nfn main() {\n    // don't modify the following two lines!\n    let (x, y) = (1, 2);\n    let s = sum(x, y);\n\n  "
  },
  {
    "path": "solutions/basic-types/numbers.md",
    "chars": 2302,
    "preview": "1.\n\n```rust\nfn main() {\n    let x: i32 = 5;\n    let mut y = 5;\n\n    y = x;\n    \n    let z = 10; // type of z : i32\n}\n```"
  },
  {
    "path": "solutions/basic-types/statements.md",
    "chars": 460,
    "preview": "1.\n\n```rust\nfn main() {\n    let v = {\n        let mut x = 1;\n        x += 2\n    };\n \n    assert_eq!(v, ());\n }\n```\n\n```r"
  },
  {
    "path": "solutions/collections/Hashmap.md",
    "chars": 3710,
    "preview": "1.\n\n```rust\n// FILL in the blanks and FIX the erros\nuse std::collections::HashMap;\nfn main() {\n    let mut scores = Hash"
  },
  {
    "path": "solutions/collections/String.md",
    "chars": 3486,
    "preview": "1.\n\n```rust\nfn main() {\n    let mut s: String = String::from(\"hello, \");\n    s.push_str(\"world\");\n    s.push('!');\n\n    "
  },
  {
    "path": "solutions/collections/Vector.md",
    "chars": 4765,
    "preview": "1.\n\n```rust\nfn main() {\n    let arr: [u8; 3] = [1, 2, 3];\n    \n    let v = Vec::from(arr);\n    is_vec(&v);\n\n    let v = "
  },
  {
    "path": "solutions/compound-types/array.md",
    "chars": 1059,
    "preview": "1.\n\n```rust\nfn main() {\n    let arr: [i32; 5] = [1, 2, 3, 4, 5];\n\n    assert!(arr.len() == 5);\n}\n```\n\n2.\n\n```rust\nfn mai"
  },
  {
    "path": "solutions/compound-types/enum.md",
    "chars": 4024,
    "preview": "1.\n\n```rust\nenum Number {\n    Zero,\n    One,\n    Two,\n}\n\nenum Number1 {\n    Zero = 0,\n    One,\n    Two,\n}\n\n// C-like enu"
  },
  {
    "path": "solutions/compound-types/slice.md",
    "chars": 1265,
    "preview": "1.\n\n```rust\nfn main() {\n    let arr = [1, 2, 3];\n    let s1: &[i32] = &arr[0..2];\n\n    let s2: &str = \"hello, world\";\n}\n"
  },
  {
    "path": "solutions/compound-types/string.md",
    "chars": 3281,
    "preview": "1.\n\n```rust\nfn main() {\n    let s: &str = \"hello, world\";\n }\n```\n\n2.\n\n```rust\nfn main() {\n    let s: Box<str> = \"hello, "
  },
  {
    "path": "solutions/compound-types/struct.md",
    "chars": 2486,
    "preview": "1.\n\n```rust\nstruct Person {\n    name: String,\n    age: u8,\n    hobby: String\n}\nfn main() {\n    let age = 30;\n    let p ="
  },
  {
    "path": "solutions/compound-types/tuple.md",
    "chars": 1040,
    "preview": "1.\n\n```rust\nfn main() {\n    let _t0: (u8,i16) = (0, -1);\n    // Tuples can be tuple's members\n    let _t1: (u8, (i16, u3"
  },
  {
    "path": "solutions/crate-module/crate.md",
    "chars": 893,
    "preview": "1. `cargo new hello-package`\n\n2. `cargo new --lib hello-package1`\n\n3. `hello-package` has a binary crate named `hello-pa"
  },
  {
    "path": "solutions/crate-module/module.md",
    "chars": 2313,
    "preview": "1.\n\n```rust\n// in lib.rs\nmod front_of_house {\n    mod hosting {\n        fn add_to_waitlist() {}\n\n        fn seat_at_tabl"
  },
  {
    "path": "solutions/crate-module/use-pub.md",
    "chars": 609,
    "preview": "1.\n\n```rust\nuse std::fmt::Result;\nuse std::io::Result as IoResult;\n\nfn main() {}\n```\n\n2.\n\n```rust\nuse std::collections::"
  },
  {
    "path": "solutions/fight-compiler/borrowing.md",
    "chars": 371,
    "preview": "1.\n\n```rust\nstruct test {\n    list: Vec<i32>,\n    a: i32\n}\n\nimpl test {\n    pub fn new() -> Self {\n        test { list:v"
  },
  {
    "path": "solutions/flow-control.md",
    "chars": 3322,
    "preview": "1.\n\n```rust\nfn main() {\n    let n = 5;\n\n    if n < 0 {\n        println!(\"{} is negative\", n);\n    } else if n > 0 {\n    "
  },
  {
    "path": "solutions/formatted-output/debug-display.md",
    "chars": 2487,
    "preview": "1.\n\n```rust\n#[derive(Debug)]\nstruct Structure(i32);\n\nfn main() {\n    // Types in std and Rust have implemented the fmt::"
  },
  {
    "path": "solutions/formatted-output/formatting.md",
    "chars": 3042,
    "preview": "1.\n\n```rust\nfn main() {\n    println!(\"{0}, this is {1}. {1}, this is {0}\", \"Alice\", \"Bob\");// => Alice, this is Bob. Bob"
  },
  {
    "path": "solutions/formatted-output/println.md",
    "chars": 262,
    "preview": "1.\n\n```rust\nfn main() {\n    let s1 = \"hello\";\n    /* Fill in the blank */\n    let s = format!(\"{}, world!\", s1);\n    ass"
  },
  {
    "path": "solutions/functional-programing/closure.md",
    "chars": 5231,
    "preview": "1. \n\n```rust\nfn main() {\n    let color = String::from(\"green\");\n\n    let print = || println!(\"`color`: {}\", color);\n\n   "
  },
  {
    "path": "solutions/functional-programing/iterator.md",
    "chars": 4616,
    "preview": "1. \n\n```rust\nfn main() {\n    let arr = [0; 10];\n    for i in arr {\n        println!(\"{}\", i)\n    }\n}\n```\n\n2. \n\n```rust\nf"
  },
  {
    "path": "solutions/generics-traits/advanced-trait.md",
    "chars": 4790,
    "preview": "1.\n\n```rust\nstruct Container(i32, i32);\n\n// A trait which checks if 2 items are stored inside of container.\n// Also retr"
  },
  {
    "path": "solutions/generics-traits/const-generics.md",
    "chars": 1273,
    "preview": "1.\n\n```rust\nstruct Array<T, const N: usize> {\n    data : [T; N]\n}\n\nfn main() {\n    let arrays = [\n        Array{\n       "
  },
  {
    "path": "solutions/generics-traits/generics.md",
    "chars": 2183,
    "preview": "1.\n\n```rust\nstruct A;          // Concrete type `A`.\nstruct S(A);       // Concrete type `S`.\nstruct SGen<T>(T); // Gene"
  },
  {
    "path": "solutions/generics-traits/trait-object.md",
    "chars": 3642,
    "preview": "1.\n\n```rust\ntrait Bird {\n    fn quack(&self) -> String;\n}\n\nstruct Duck;\nimpl Duck {\n    fn swim(&self) {\n        println"
  },
  {
    "path": "solutions/generics-traits/traits.md",
    "chars": 8307,
    "preview": "1.\n\n```rust\ntrait Hello {\n    fn say_hi(&self) -> String {\n        String::from(\"hi\")\n    }\n\n    fn say_something(&self)"
  },
  {
    "path": "solutions/lifetime/advance.md",
    "chars": 2163,
    "preview": "1. \n\n```rust\nstruct DoubleRef<'a,'b:'a, T> {\n    r: &'a T,\n    s: &'b T\n}\nfn main() {\n    println!(\"Success!\")\n}\n```\n\n2."
  },
  {
    "path": "solutions/lifetime/basic.md",
    "chars": 4624,
    "preview": "# Lifetime\n\n1.\n\n```rust\nfn main() {\n    let i = 3; // Lifetime for `i` starts. ────────────────┐\n    //                 "
  },
  {
    "path": "solutions/lifetime/static.md",
    "chars": 1645,
    "preview": "1. \n\n```rust\nfn main() {\n    let v: &str = \"hello\";\n    need_static(v);\n\n    println!(\"Success!\")\n}\n\nfn need_static(r : "
  },
  {
    "path": "solutions/method.md",
    "chars": 2487,
    "preview": "1.\n\n```rust\nstruct Rectangle {\n    width: u32,\n    height: u32,\n}\n\nimpl Rectangle {\n    fn area(&self) -> u32 {\n        "
  },
  {
    "path": "solutions/newtype-sized.md",
    "chars": 2726,
    "preview": "1. \n\n```rust\nuse std::fmt;\n\nstruct Wrapper(Vec<String>);\n\nimpl fmt::Display for Wrapper {\n    fn fmt(&self, f: &mut fmt:"
  },
  {
    "path": "solutions/ownership/borrowing.md",
    "chars": 2034,
    "preview": "1.\n\n```rust\nfn main() {\n    let x = 5;\n    // fill the blank\n    let p = &x;\n \n    println!(\"the memory address of x is "
  },
  {
    "path": "solutions/ownership/ownership.md",
    "chars": 2721,
    "preview": "1.\n\n```rust\nfn main() {\n    let x = String::from(\"hello, world\");\n    let y = x.clone();\n    println!(\"{},{}\",x,y);\n}\n``"
  },
  {
    "path": "solutions/pattern-match/match.md",
    "chars": 2868,
    "preview": "1.\n\n```rust\nenum Direction {\n    East,\n    West,\n    North,\n    South,\n}\n\nfn main() {\n    let dire = Direction::South;\n "
  },
  {
    "path": "solutions/pattern-match/patterns.md",
    "chars": 2004,
    "preview": "1.\n\n```rust\nfn main() {}\nfn match_number(n: i32) {\n    match n {\n        // match a single value\n        1 => println!(\""
  },
  {
    "path": "solutions/result-panic/panic.md",
    "chars": 1346,
    "preview": "1.\n\n```rust\nuse core::panic;\n\nfn drink(beverage: &str) {\n    if beverage == \"lemonade\" {\n        println!(\"Success!\");\n "
  },
  {
    "path": "solutions/result-panic/result.md",
    "chars": 3824,
    "preview": "1.\n\n```rust\nuse std::num::ParseIntError;\n\nfn multiply(n1_str: &str, n2_str: &str) -> Result<i32, ParseIntError> {\n    le"
  },
  {
    "path": "solutions/type-conversions/as.md",
    "chars": 2111,
    "preview": "1.\n\n```rust\nfn main() {\n    let decimal = 97.123_f32;\n\n    let integer: u8 = decimal as u8;\n\n    let c1: char = decimal "
  },
  {
    "path": "solutions/type-conversions/from-into.md",
    "chars": 2598,
    "preview": "1.\n\n```rust\nfn main() {\n    // impl From<bool> for i32\n    let i1: i32 = false.into();\n    let i2: i32 = i32::from(false"
  },
  {
    "path": "solutions/type-conversions/others.md",
    "chars": 1539,
    "preview": "1\n\n```rust\nuse std::fmt;\n\nstruct Point {\n    x: i32,\n    y: i32,\n}\n\nimpl fmt::Display for Point {\n    fn fmt(&self, f: &"
  },
  {
    "path": "solutions/variables.md",
    "chars": 1862,
    "preview": "1.\n\n```rust\nfn main() {\n    let x: i32 = 5; // uninitialized but using, ERROR !\n    let y: i32; // uninitialized but als"
  },
  {
    "path": "zh-CN/assets/CNAME",
    "chars": 21,
    "preview": "practice-zh.course.rs"
  },
  {
    "path": "zh-CN/assets/custom3.js",
    "chars": 5574,
    "preview": "var initAll = function () {\n    var path = window.location.pathname;\n    if (path.endsWith(\"/print.html\")) {\n        ret"
  },
  {
    "path": "zh-CN/assets/lang1.js",
    "chars": 864,
    "preview": "(function () {\n  var path = window.location.pathname;\n  var link = \"https://practice.course.rs\" + path;\n  var word = \"En"
  },
  {
    "path": "zh-CN/assets/mini-redis/.github/workflows/ci.yml",
    "chars": 397,
    "preview": "name: CI\n\non:\n  push:\n    branches: [ master ]\n  pull_request:\n    branches: [ master ]\n\njobs:\n  build:\n\n    runs-on: ub"
  },
  {
    "path": "zh-CN/assets/mini-redis/.gitignore",
    "chars": 19,
    "preview": "/target\n**/*.rs.bk\n"
  },
  {
    "path": "zh-CN/assets/mini-redis/Cargo.toml",
    "chars": 908,
    "preview": "[package]\nauthors = [\"Carl Lerche <me@carllerche.com>\"]\nedition = \"2018\"\nname = \"mini-redis\"\nversion = \"0.4.1\"\nlicense ="
  },
  {
    "path": "zh-CN/assets/mini-redis/LICENSE",
    "chars": 1062,
    "preview": "Copyright (c) 2020 Tokio Contributors\n\nPermission is hereby granted, free of charge, to any\nperson obtaining a copy of t"
  },
  {
    "path": "zh-CN/assets/mini-redis/README.md",
    "chars": 5833,
    "preview": "# mini-redis\n\n本项目从[tokio/mini-redis](https://github.com/tokio-rs/mini-redis)fork而来,作为rust course的练习项目之一,**文档和注释还未进行翻译**,"
  },
  {
    "path": "zh-CN/assets/mini-redis/examples/chat.rs",
    "chars": 57,
    "preview": "#[tokio::main]\nasync fn main() {\n    unimplemented!();\n}\n"
  },
  {
    "path": "zh-CN/assets/mini-redis/examples/hello_world.rs",
    "chars": 819,
    "preview": "//! Hello world server.\n//!\n//! A simple client that connects to a mini-redis server, sets key \"hello\" with value \"world"
  },
  {
    "path": "zh-CN/assets/mini-redis/examples/pub.rs",
    "chars": 720,
    "preview": "//! Publish to a redis channel example.\n//!\n//! A simple client that connects to a mini-redis server, and\n//! publishes "
  },
  {
    "path": "zh-CN/assets/mini-redis/examples/sub.rs",
    "chars": 982,
    "preview": "//! Subscribe to a redis channel example.\n//!\n//! A simple client that connects to a mini-redis server, subscribes to \"f"
  },
  {
    "path": "zh-CN/assets/mini-redis/src/bin/cli.rs",
    "chars": 2940,
    "preview": "use mini_redis::{client, DEFAULT_PORT};\n\nuse bytes::Bytes;\nuse std::num::ParseIntError;\nuse std::str;\nuse std::time::Dur"
  },
  {
    "path": "zh-CN/assets/mini-redis/src/bin/server.rs",
    "chars": 1069,
    "preview": "//! mini-redis server.\n//!\n//! This file is the entry point for the server implemented in the library. It\n//! performs c"
  },
  {
    "path": "zh-CN/assets/mini-redis/src/blocking_client.rs",
    "chars": 8603,
    "preview": "//! Minimal blocking Redis client implementation\n//!\n//! Provides a blocking connect and methods for issuing the support"
  },
  {
    "path": "zh-CN/assets/mini-redis/src/buffer.rs",
    "chars": 4375,
    "preview": "use crate::client::Client;\nuse crate::Result;\n\nuse bytes::Bytes;\nuse tokio::sync::mpsc::{channel, Receiver, Sender};\nuse"
  },
  {
    "path": "zh-CN/assets/mini-redis/src/client.rs",
    "chars": 17359,
    "preview": "//! Minimal Redis client implementation\n//!\n//! Provides an async connect and methods for issuing the supported commands"
  },
  {
    "path": "zh-CN/assets/mini-redis/src/cmd/get.rs",
    "chars": 2789,
    "preview": "use crate::{Connection, Db, Frame, Parse};\n\nuse bytes::Bytes;\nuse tracing::{debug, instrument};\n\n/// Get the value of ke"
  },
  {
    "path": "zh-CN/assets/mini-redis/src/cmd/mod.rs",
    "chars": 4070,
    "preview": "mod get;\npub use get::Get;\n\nmod publish;\npub use publish::Publish;\n\nmod set;\npub use set::Set;\n\nmod subscribe;\npub use s"
  },
  {
    "path": "zh-CN/assets/mini-redis/src/cmd/publish.rs",
    "chars": 3513,
    "preview": "use crate::{Connection, Db, Frame, Parse};\n\nuse bytes::Bytes;\n\n/// Posts a message to the given channel.\n///\n/// Send a "
  },
  {
    "path": "zh-CN/assets/mini-redis/src/cmd/set.rs",
    "chars": 5459,
    "preview": "use crate::cmd::{Parse, ParseError};\nuse crate::{Connection, Db, Frame};\n\nuse bytes::Bytes;\nuse std::time::Duration;\nuse"
  },
  {
    "path": "zh-CN/assets/mini-redis/src/cmd/subscribe.rs",
    "chars": 12843,
    "preview": "use crate::cmd::{Parse, ParseError, Unknown};\nuse crate::{Command, Connection, Db, Frame, Shutdown};\n\nuse bytes::Bytes;\n"
  },
  {
    "path": "zh-CN/assets/mini-redis/src/cmd/unknown.rs",
    "chars": 1032,
    "preview": "use crate::{Connection, Frame};\n\nuse tracing::{debug, instrument};\n\n/// Represents an \"unknown\" command. This is not a r"
  },
  {
    "path": "zh-CN/assets/mini-redis/src/connection.rs",
    "chars": 10419,
    "preview": "use crate::frame::{self, Frame};\n\nuse bytes::{Buf, BytesMut};\nuse std::io::{self, Cursor};\nuse tokio::io::{AsyncReadExt,"
  },
  {
    "path": "zh-CN/assets/mini-redis/src/db.rs",
    "chars": 14403,
    "preview": "use tokio::sync::{broadcast, Notify};\nuse tokio::time::{self, Duration, Instant};\n\nuse bytes::Bytes;\nuse std::collection"
  },
  {
    "path": "zh-CN/assets/mini-redis/src/frame.rs",
    "chars": 8050,
    "preview": "//! Provides a type representing a Redis protocol frame as well as utilities for\n//! parsing frames from a byte array.\n\n"
  },
  {
    "path": "zh-CN/assets/mini-redis/src/lib.rs",
    "chars": 2362,
    "preview": "//! A minimal (i.e. very incomplete) implementation of a Redis server and\n//! client.\n//!\n//! The purpose of this projec"
  },
  {
    "path": "zh-CN/assets/mini-redis/src/parse.rs",
    "chars": 5066,
    "preview": "use crate::Frame;\n\nuse bytes::Bytes;\nuse std::{fmt, str, vec};\n\n/// Utility for parsing a command\n///\n/// Commands are r"
  },
  {
    "path": "zh-CN/assets/mini-redis/src/server.rs",
    "chars": 16927,
    "preview": "//! Minimal Redis server implementation\n//!\n//! Provides an async `run` function that listens for inbound connections,\n/"
  },
  {
    "path": "zh-CN/assets/mini-redis/src/shutdown.rs",
    "chars": 1523,
    "preview": "use tokio::sync::broadcast;\n\n/// Listens for the server shutdown signal.\n///\n/// Shutdown is signalled using a `broadcas"
  },
  {
    "path": "zh-CN/assets/mini-redis/tests/buffer.rs",
    "chars": 1018,
    "preview": "use mini_redis::{buffer, client, server};\nuse std::net::SocketAddr;\nuse tokio::net::TcpListener;\nuse tokio::task::JoinHa"
  },
  {
    "path": "zh-CN/assets/mini-redis/tests/client.rs",
    "chars": 3202,
    "preview": "use mini_redis::{client, server};\nuse std::net::SocketAddr;\nuse tokio::net::TcpListener;\nuse tokio::task::JoinHandle;\n\n/"
  },
  {
    "path": "zh-CN/assets/mini-redis/tests/server.rs",
    "chars": 11727,
    "preview": "use mini_redis::server;\n\nuse std::net::SocketAddr;\nuse tokio::io::{AsyncReadExt, AsyncWriteExt};\nuse tokio::net::{TcpLis"
  },
  {
    "path": "zh-CN/book.toml",
    "chars": 637,
    "preview": "[book]\ntitle = \"Rust By Practice( Rust 练习实践 )\"\ndescription = \"Learning Rust By Practice, narrowing the gap between begin"
  },
  {
    "path": "zh-CN/deploy.sh",
    "chars": 511,
    "preview": "## this script deploys the static website of course.rs to github pages\n\n## build static website for book\nmdbook build\n##"
  },
  {
    "path": "zh-CN/src/SUMMARY.md",
    "chars": 3429,
    "preview": "# Summary\n\n- [关于 practice.rs](why-exercise.md)\n- [值得学习的小型项目](elegant-code-base.md)\n- [变量绑定与解构](variables.md)\n- [基本类型](ba"
  }
]

// ... and 94 more files (download for full content)

About this extraction

This page contains the full source code of the sunface/rust-by-practice GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 294 files (722.1 KB), approximately 219.4k tokens, and a symbol index with 195 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!