Showing preview only (2,014K chars total). Download the full file or copy to clipboard to get everything.
Repository: sunface/rust-course
Branch: main
Commit: f9243311ec83
Files: 535
Total size: 1.8 MB
Directory structure:
gitextract_g9fgxovm/
├── .github/
│ └── workflows/
│ ├── ci.yml
│ └── deploy.yml
├── .gitignore
├── README.md
├── assets/
│ ├── CNAME
│ ├── bigPicture.js
│ ├── custom.js
│ ├── rustlings-zh/
│ │ ├── .all-contributorsrc
│ │ ├── .clog.toml
│ │ ├── .editorconfig
│ │ ├── .gitignore
│ │ ├── .gitpod.yml
│ │ ├── .replit
│ │ ├── CHANGELOG.md
│ │ ├── CONTRIBUTING.md
│ │ ├── Cargo.toml
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── default_out.txt
│ │ ├── exercises/
│ │ │ ├── README.md
│ │ │ ├── advanced_errors/
│ │ │ │ ├── advanced_errs1.rs
│ │ │ │ └── advanced_errs2.rs
│ │ │ ├── clippy/
│ │ │ │ ├── README.md
│ │ │ │ ├── clippy1.rs
│ │ │ │ └── clippy2.rs
│ │ │ ├── collections/
│ │ │ │ ├── README.md
│ │ │ │ ├── hashmap1.rs
│ │ │ │ ├── hashmap2.rs
│ │ │ │ ├── vec1.rs
│ │ │ │ └── vec2.rs
│ │ │ ├── conversions/
│ │ │ │ ├── README.md
│ │ │ │ ├── as_ref_mut.rs
│ │ │ │ ├── from_into.rs
│ │ │ │ ├── from_str.rs
│ │ │ │ ├── try_from_into.rs
│ │ │ │ └── using_as.rs
│ │ │ ├── enums/
│ │ │ │ ├── README.md
│ │ │ │ ├── enums1.rs
│ │ │ │ ├── enums2.rs
│ │ │ │ └── enums3.rs
│ │ │ ├── error_handling/
│ │ │ │ ├── README.md
│ │ │ │ ├── errors1.rs
│ │ │ │ ├── errors2.rs
│ │ │ │ ├── errors3.rs
│ │ │ │ ├── errors4.rs
│ │ │ │ ├── errors5.rs
│ │ │ │ └── errors6.rs
│ │ │ ├── functions/
│ │ │ │ ├── README.md
│ │ │ │ ├── functions1.rs
│ │ │ │ ├── functions2.rs
│ │ │ │ ├── functions3.rs
│ │ │ │ ├── functions4.rs
│ │ │ │ └── functions5.rs
│ │ │ ├── generics/
│ │ │ │ ├── README.md
│ │ │ │ ├── generics1.rs
│ │ │ │ ├── generics2.rs
│ │ │ │ └── generics3.rs
│ │ │ ├── if/
│ │ │ │ ├── README.md
│ │ │ │ ├── if1.rs
│ │ │ │ └── if2.rs
│ │ │ ├── macros/
│ │ │ │ ├── README.md
│ │ │ │ ├── macros1.rs
│ │ │ │ ├── macros2.rs
│ │ │ │ ├── macros3.rs
│ │ │ │ └── macros4.rs
│ │ │ ├── modules/
│ │ │ │ ├── README.md
│ │ │ │ ├── modules1.rs
│ │ │ │ ├── modules2.rs
│ │ │ │ └── modules3.rs
│ │ │ ├── move_semantics/
│ │ │ │ ├── README.md
│ │ │ │ ├── move_semantics1.rs
│ │ │ │ ├── move_semantics2.rs
│ │ │ │ ├── move_semantics3.rs
│ │ │ │ ├── move_semantics4.rs
│ │ │ │ └── move_semantics5.rs
│ │ │ ├── option/
│ │ │ │ ├── README.md
│ │ │ │ ├── option1.rs
│ │ │ │ ├── option2.rs
│ │ │ │ └── option3.rs
│ │ │ ├── primitive_types/
│ │ │ │ ├── README.md
│ │ │ │ ├── primitive_types1.rs
│ │ │ │ ├── primitive_types2.rs
│ │ │ │ ├── primitive_types3.rs
│ │ │ │ ├── primitive_types4.rs
│ │ │ │ ├── primitive_types5.rs
│ │ │ │ └── primitive_types6.rs
│ │ │ ├── quiz1.rs
│ │ │ ├── quiz2.rs
│ │ │ ├── quiz3.rs
│ │ │ ├── quiz4.rs
│ │ │ ├── standard_library_types/
│ │ │ │ ├── README.md
│ │ │ │ ├── arc1.rs
│ │ │ │ ├── box1.rs
│ │ │ │ ├── iterators1.rs
│ │ │ │ ├── iterators2.rs
│ │ │ │ ├── iterators3.rs
│ │ │ │ ├── iterators4.rs
│ │ │ │ └── iterators5.rs
│ │ │ ├── strings/
│ │ │ │ ├── README.md
│ │ │ │ ├── strings1.rs
│ │ │ │ └── strings2.rs
│ │ │ ├── structs/
│ │ │ │ ├── README.md
│ │ │ │ ├── structs1.rs
│ │ │ │ ├── structs2.rs
│ │ │ │ └── structs3.rs
│ │ │ ├── tests/
│ │ │ │ ├── README.md
│ │ │ │ ├── tests1.rs
│ │ │ │ ├── tests2.rs
│ │ │ │ └── tests3.rs
│ │ │ ├── threads/
│ │ │ │ ├── README.md
│ │ │ │ └── threads1.rs
│ │ │ ├── traits/
│ │ │ │ ├── README.md
│ │ │ │ ├── traits1.rs
│ │ │ │ └── traits2.rs
│ │ │ └── variables/
│ │ │ ├── README.md
│ │ │ ├── variables1.rs
│ │ │ ├── variables2.rs
│ │ │ ├── variables3.rs
│ │ │ ├── variables4.rs
│ │ │ ├── variables5.rs
│ │ │ └── variables6.rs
│ │ ├── info.toml
│ │ ├── install.ps1
│ │ ├── install.sh
│ │ ├── src/
│ │ │ ├── exercise.rs
│ │ │ ├── main.rs
│ │ │ ├── run.rs
│ │ │ ├── ui.rs
│ │ │ └── verify.rs
│ │ └── tests/
│ │ ├── fixture/
│ │ │ ├── failure/
│ │ │ │ ├── compFailure.rs
│ │ │ │ ├── compNoExercise.rs
│ │ │ │ ├── info.toml
│ │ │ │ ├── testFailure.rs
│ │ │ │ └── testNotPassed.rs
│ │ │ ├── state/
│ │ │ │ ├── finished_exercise.rs
│ │ │ │ ├── info.toml
│ │ │ │ ├── pending_exercise.rs
│ │ │ │ └── pending_test_exercise.rs
│ │ │ └── success/
│ │ │ ├── compSuccess.rs
│ │ │ ├── info.toml
│ │ │ └── testSuccess.rs
│ │ └── integration_tests.rs
│ ├── sitemap.xml
│ └── writing-material/
│ ├── books.md
│ ├── courses.md
│ ├── demos_for_learning.md
│ ├── good-sourcecode.md
│ ├── posts/
│ │ ├── Iterator.md
│ │ ├── SIMD.md
│ │ ├── atomic.md
│ │ ├── attributes.md
│ │ ├── fight-with-compiler-check/
│ │ │ ├── borrow.md
│ │ │ └── generic.md
│ │ ├── file.md
│ │ ├── function_signature.md
│ │ ├── generics.md
│ │ ├── hashmap.md
│ │ ├── identifier.md
│ │ ├── images.md
│ │ ├── interview.md
│ │ ├── io.md
│ │ ├── lifetime.md
│ │ ├── lifetime_elision_rules.md
│ │ ├── non-lexical-lifetime.md
│ │ ├── operators.md
│ │ ├── package.md
│ │ ├── performance.md
│ │ ├── plugins.md
│ │ ├── reference.md
│ │ ├── rust-analyser.md
│ │ ├── self-referential.md
│ │ ├── string.md
│ │ ├── system_command.md
│ │ ├── tests/
│ │ │ ├── doc_test.md
│ │ │ ├── integration_test.md
│ │ │ ├── misc.md
│ │ │ └── unit_test.md
│ │ ├── threads.md
│ │ ├── to_resolved.md
│ │ ├── tokio.md
│ │ ├── trivia.md
│ │ └── wasm.md
│ ├── style_guide/
│ │ ├── coding.md
│ │ └── naming.md
│ └── 读者疑惑的点记录.md
├── book.toml
├── ci/
│ └── copy-assets.sh
├── deploy.sh
├── genpdf.sh
├── src/
│ ├── SUMMARY.md
│ ├── about-book.md
│ ├── advance/
│ │ ├── async/
│ │ │ ├── async-await.md
│ │ │ ├── future-excuting.md
│ │ │ ├── getting-started.md
│ │ │ ├── intro.md
│ │ │ ├── multi-futures-simultaneous.md
│ │ │ ├── pain-points-and-workarounds.md
│ │ │ ├── pin-unpin.md
│ │ │ └── web-server.md
│ │ ├── circle-self-ref/
│ │ │ ├── circle-reference.md
│ │ │ ├── intro.md
│ │ │ └── self-referential.md
│ │ ├── concurrency-with-threads/
│ │ │ ├── concurrency-parallelism.md
│ │ │ ├── intro.md
│ │ │ ├── message-passing.md
│ │ │ ├── races.md
│ │ │ ├── ref-counter-lock.md
│ │ │ ├── send-sync.md
│ │ │ ├── sync1.md
│ │ │ ├── sync2.md
│ │ │ └── thread.md
│ │ ├── difficulties/
│ │ │ └── pointer.md
│ │ ├── errors.md
│ │ ├── functional-programing/
│ │ │ ├── closure.md
│ │ │ ├── intro.md
│ │ │ └── iterator.md
│ │ ├── global-variable.md
│ │ ├── hrtb.md
│ │ ├── into-types/
│ │ │ ├── converse.md
│ │ │ ├── custom-type.md
│ │ │ ├── enum-int.md
│ │ │ ├── intro.md
│ │ │ └── sized.md
│ │ ├── intro.md
│ │ ├── lifetime/
│ │ │ ├── advance.md
│ │ │ ├── intro.md
│ │ │ ├── misconceptions.md
│ │ │ └── static.md
│ │ ├── macro.md
│ │ ├── simd.md
│ │ ├── smart-pointer/
│ │ │ ├── box.md
│ │ │ ├── cell-refcell.md
│ │ │ ├── deref.md
│ │ │ ├── drop.md
│ │ │ ├── intro.md
│ │ │ └── rc-arc.md
│ │ └── unsafe/
│ │ ├── inline-asm.md
│ │ ├── intro.md
│ │ ├── superpowers.md
│ │ └── ub.md
│ ├── advance-practice/
│ │ ├── async.md
│ │ ├── bridging-with-sync.md
│ │ ├── channels.md
│ │ ├── design-pattern.md
│ │ ├── frame.md
│ │ ├── getting-startted.md
│ │ ├── graceful-shutdown.md
│ │ ├── intro.md
│ │ ├── io.md
│ │ ├── overview.md
│ │ ├── select.md
│ │ ├── shared-state.md
│ │ ├── spawning.md
│ │ └── stream.md
│ ├── advance-practice1/
│ │ ├── graceful-shutdown.md
│ │ ├── intro.md
│ │ ├── multi-threads.md
│ │ └── web-server.md
│ ├── appendix/
│ │ ├── derive.md
│ │ ├── difficulties.md
│ │ ├── expressions.md
│ │ ├── intro.md
│ │ ├── keywords.md
│ │ ├── operators.md
│ │ ├── prelude.md
│ │ ├── rust-version.md
│ │ └── rust-versions/
│ │ ├── 1.58.md
│ │ ├── 1.59.md
│ │ ├── 1.60.md
│ │ ├── 1.61.md
│ │ ├── 1.62.md
│ │ ├── 1.63.md
│ │ ├── 1.64.md
│ │ ├── 1.65.md
│ │ ├── 1.66.md
│ │ ├── 1.67.md
│ │ ├── 1.68.md
│ │ ├── 1.69.md
│ │ ├── 1.70.md
│ │ ├── 1.71.md
│ │ ├── 1.72.md
│ │ ├── 1.73.md
│ │ ├── 1.74.md
│ │ ├── 1.75.md
│ │ ├── 1.76.md
│ │ ├── 1.77.md
│ │ ├── 1.78.md
│ │ ├── 1.79.md
│ │ ├── 1.80.md
│ │ ├── 1.81.md
│ │ ├── 1.82.md
│ │ ├── 1.83.md
│ │ ├── 1.84.md
│ │ ├── 1.85.md
│ │ ├── 1.86.md
│ │ ├── 1.87.md
│ │ ├── 1.88.md
│ │ ├── 1.89.md
│ │ └── intro.md
│ ├── basic/
│ │ ├── base-type/
│ │ │ ├── char-bool.md
│ │ │ ├── function.md
│ │ │ ├── index.md
│ │ │ ├── numbers.md
│ │ │ └── statement-expression.md
│ │ ├── collections/
│ │ │ ├── hashmap.md
│ │ │ ├── intro.md
│ │ │ └── vector.md
│ │ ├── comment.md
│ │ ├── compound-type/
│ │ │ ├── array.md
│ │ │ ├── enum.md
│ │ │ ├── intro.md
│ │ │ ├── string-slice.md
│ │ │ ├── struct.md
│ │ │ └── tuple.md
│ │ ├── crate-module/
│ │ │ ├── crate.md
│ │ │ ├── intro.md
│ │ │ ├── module.md
│ │ │ └── use.md
│ │ ├── flow-control.md
│ │ ├── formatted-output.md
│ │ ├── intro.md
│ │ ├── lifetime.md
│ │ ├── match-pattern/
│ │ │ ├── all-patterns.md
│ │ │ ├── intro.md
│ │ │ ├── match-if-let.md
│ │ │ ├── option.md
│ │ │ └── pattern-match.md
│ │ ├── method.md
│ │ ├── ownership/
│ │ │ ├── borrowing.md
│ │ │ ├── index.md
│ │ │ └── ownership.md
│ │ ├── result-error/
│ │ │ ├── intro.md
│ │ │ ├── panic.md
│ │ │ └── result.md
│ │ ├── trait/
│ │ │ ├── advance-trait.md
│ │ │ ├── generic.md
│ │ │ ├── intro.md
│ │ │ ├── trait-object.md
│ │ │ └── trait.md
│ │ └── variable.md
│ ├── basic-practice/
│ │ ├── base-features.md
│ │ ├── envs.md
│ │ ├── intro.md
│ │ ├── iterators.md
│ │ ├── refactoring.md
│ │ ├── stderr.md
│ │ └── tests.md
│ ├── beat-ai.md
│ ├── cargo/
│ │ ├── getting-started.md
│ │ ├── git-auth.md
│ │ ├── guide/
│ │ │ ├── build-cache.md
│ │ │ ├── cargo-cache.md
│ │ │ ├── cargo-toml-lock.md
│ │ │ ├── dependencies.md
│ │ │ ├── download-package.md
│ │ │ ├── intro.md
│ │ │ ├── package-layout.md
│ │ │ ├── tests-ci.md
│ │ │ └── why-exist.md
│ │ ├── intro.md
│ │ └── reference/
│ │ ├── build-script/
│ │ │ ├── examples.md
│ │ │ └── intro.md
│ │ ├── cargo-target.md
│ │ ├── configuration.md
│ │ ├── deps-overriding.md
│ │ ├── env.md
│ │ ├── features/
│ │ │ ├── examples.md
│ │ │ └── intro.md
│ │ ├── intro.md
│ │ ├── manifest.md
│ │ ├── package-id.md
│ │ ├── profile.md
│ │ ├── profiles.md
│ │ ├── publishing-on-crates.io.md
│ │ ├── specify-deps.md
│ │ └── workspaces.md
│ ├── community.md
│ ├── compiler/
│ │ ├── fight-with-compiler/
│ │ │ ├── borrowing/
│ │ │ │ ├── borrow-distinct-fields-of-struct.md
│ │ │ │ ├── intro.md
│ │ │ │ └── ref-exist-in-out-fn.md
│ │ │ ├── intro.md
│ │ │ ├── lifetime/
│ │ │ │ ├── closure-with-static.md
│ │ │ │ ├── intro.md
│ │ │ │ ├── loop.md
│ │ │ │ ├── too-long1.md
│ │ │ │ └── too-long2.md
│ │ │ ├── phantom-data.md
│ │ │ └── unconstrained.md
│ │ ├── intro.md
│ │ └── pitfalls/
│ │ ├── arithmetic-overflow.md
│ │ ├── closure-with-lifetime.md
│ │ ├── index.md
│ │ ├── iterator-everywhere.md
│ │ ├── lazy-iterators.md
│ │ ├── main-with-channel-blocked.md
│ │ ├── multiple-mutable-references.md
│ │ ├── stack-overflow.md
│ │ ├── the-disabled-mutability.md
│ │ ├── use-vec-in-for.md
│ │ ├── utf8-performance.md
│ │ └── weird-ranges.md
│ ├── difficulties/
│ │ ├── cow.md
│ │ ├── eq.md
│ │ ├── intro.md
│ │ ├── lifetime.md
│ │ ├── move-copy.md
│ │ ├── pointer.md
│ │ ├── slice.md
│ │ └── string.md
│ ├── first-try/
│ │ ├── cargo.md
│ │ ├── editor.md
│ │ ├── hello-world.md
│ │ ├── installation.md
│ │ ├── intro.md
│ │ ├── slowly-downloading.md
│ │ └── sth-you-should-not-do.md
│ ├── github.md
│ ├── index-list.md
│ ├── into-rust.md
│ ├── libraries/
│ │ ├── command/
│ │ │ ├── intro.md
│ │ │ └── structopt.md
│ │ ├── http/
│ │ │ ├── intro.md
│ │ │ └── reqwest.md
│ │ ├── intro.md
│ │ └── json/
│ │ ├── intro.md
│ │ └── serde.md
│ ├── logs/
│ │ ├── about-log.md
│ │ ├── intro.md
│ │ ├── log.md
│ │ ├── observe/
│ │ │ ├── about-observe.md
│ │ │ ├── intro.md
│ │ │ └── trace.md
│ │ ├── tracing-logger.md
│ │ └── tracing.md
│ ├── practice/
│ │ ├── best-pratice.md
│ │ ├── interview.md
│ │ ├── intro.md
│ │ ├── naming.md
│ │ └── third-party-libs.md
│ ├── practice.md
│ ├── profiling/
│ │ ├── compiler/
│ │ │ ├── attributes.md
│ │ │ ├── intro.md
│ │ │ ├── llvm.md
│ │ │ ├── optimization/
│ │ │ │ ├── intro.md
│ │ │ │ └── option.md
│ │ │ ├── phantom-data.md
│ │ │ └── speed-up.md
│ │ ├── intro.md
│ │ ├── memory/
│ │ │ ├── allocation.md
│ │ │ ├── intro.md
│ │ │ ├── layout.md
│ │ │ ├── pointer-ref.md
│ │ │ ├── uninit.md
│ │ │ └── virtual.md
│ │ ├── performance/
│ │ │ ├── allocator.md
│ │ │ ├── calculate.md
│ │ │ ├── clone-copy.md
│ │ │ ├── cpu-cache.md
│ │ │ ├── deep-into-move.md
│ │ │ ├── early-optimise.md
│ │ │ ├── enum.md
│ │ │ ├── heap-stack.md
│ │ │ ├── intro.md
│ │ │ ├── runtime-check.md
│ │ │ ├── string.md
│ │ │ └── tools.md
│ │ └── profiling/
│ │ └── performance/
│ │ └── benchmark.md
│ ├── rust-weekly.md
│ ├── rustt.md
│ ├── rusty-book.md
│ ├── some-thoughts.md
│ ├── std/
│ │ ├── hashmap.md
│ │ ├── intro.md
│ │ ├── iterator.md
│ │ ├── search.md
│ │ └── vector.md
│ ├── templates/
│ │ ├── files/
│ │ │ ├── dir.md
│ │ │ └── intro.md
│ │ ├── http/
│ │ │ └── intro.md
│ │ └── intro.md
│ ├── test/
│ │ ├── assertion.md
│ │ ├── benchmark.md
│ │ ├── ci.md
│ │ ├── intro.md
│ │ ├── unit-integration-test.md
│ │ └── write-tests.md
│ ├── too-many-lists/
│ │ ├── advanced-lists/
│ │ │ ├── double-singly.md
│ │ │ ├── intro.md
│ │ │ ├── stack-allocated.md
│ │ │ └── unsafe-deque.md
│ │ ├── bad-stack/
│ │ │ ├── basic-operations.md
│ │ │ ├── final-code.md
│ │ │ ├── intro.md
│ │ │ └── layout.md
│ │ ├── deque/
│ │ │ ├── final-code.md
│ │ │ ├── intro.md
│ │ │ ├── iterator.md
│ │ │ ├── layout.md
│ │ │ ├── peek.md
│ │ │ └── symmetric.md
│ │ ├── do-we-need-it.md
│ │ ├── intro.md
│ │ ├── ok-stack/
│ │ │ ├── intro.md
│ │ │ ├── iter.md
│ │ │ ├── itermut.md
│ │ │ ├── peek.md
│ │ │ └── type-optimizing.md
│ │ ├── persistent-stack/
│ │ │ ├── drop-arc.md
│ │ │ ├── intro.md
│ │ │ └── layout.md
│ │ ├── production-unsafe-deque/
│ │ │ ├── basics.md
│ │ │ ├── boring-combinatorics.md
│ │ │ ├── drop-and-panic-safety.md
│ │ │ ├── filling-in-random-bits.md
│ │ │ ├── final-code.md
│ │ │ ├── implementing-cursors.md
│ │ │ ├── intro.md
│ │ │ ├── layout.md
│ │ │ ├── send-sync-and-compile-tests.md
│ │ │ ├── testing-cursors.md
│ │ │ ├── testing.md
│ │ │ └── variance-and-phantomData.md
│ │ └── unsafe-queue/
│ │ ├── basics.md
│ │ ├── extra-junk.md
│ │ ├── final-code.md
│ │ ├── intro.md
│ │ ├── layout.md
│ │ ├── layout2.md
│ │ ├── miri.md
│ │ ├── stacked-borrow.md
│ │ └── testing-stacked-borrow.md
│ └── usecases/
│ ├── aws-rust.md
│ └── intro.md
└── theme/
├── index1.hbs
└── style.css
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/workflows/ci.yml
================================================
name: CI
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
test:
name: test
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
steps:
- uses: actions/checkout@v4
- name: Install Rust
run: |
rustup set profile minimal
rustup toolchain install stable
rustup default stable
- name: Setup mdBook
uses: peaceiris/actions-mdbook@v2
with:
mdbook-version: "latest"
- name: Run tests
run: mdbook test
================================================
FILE: .github/workflows/deploy.yml
================================================
name: Deploy
on:
push:
branches:
- main
pull_request:
branches:
- main
defaults:
run:
shell: bash
permissions:
contents: write
jobs:
deploy:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
steps:
- uses: actions/checkout@v4
- name: Install Rust
run: |
rustup set profile minimal
rustup toolchain install stable
rustup default stable
- name: Setup mdBook
uses: peaceiris/actions-mdbook@v2
with:
mdbook-version: "latest"
- run: mdbook build
- name: Copy Assets
run: |
chmod +x ci/copy-assets.sh
ci/copy-assets.sh ${{ matrix.os }}
- name: Deploy
uses: peaceiris/actions-gh-pages@v3
if: ${{ github.ref == 'refs/heads/main' }}
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./book
================================================
FILE: .gitignore
================================================
.DS_Store
book
Changelog.md
dump.rdb
================================================
FILE: README.md
================================================
<h1 align="center">Rust语言圣经</h1>
<div align="center">
<img src="https://github.com/sunface/rust-course/blob/main/assets/banner.jpg?raw=true">
</div>
<div align="center">
[](https://github.com/rustlang-cn) [](https://github.com/sunface/rust-course/stargazers)
[](https://github.com/sunface/rust-course/issues)
[](https://mybinder.org/v2/gh/ines/spacy-course/master)
<!-- <a href="https://www.zhihu.com/column/c_1452781034895446017">
<img alt="Sunface | 知乎" height="20px" width="20px" src="https://github.com/sunface/rust-course/blob/main/assets/zhihu.jpg">
</a> -->
</div>
## 教程简介
- 在线阅读: https://course.rs
**`Rust语言圣经`**涵盖从**入门到精通**所需的 Rust 知识,目录及内容都经过深思熟虑的设计,同时语言生动幽默,行文流畅自如,摆脱技术书籍常有的机器味和晦涩感。
- **深入度**,在基础教学的同时,提供了深入剖析。浅尝辄止并不能让我们站上紫禁之巅
- **专题内容**,将 Rust 高级内容通过专题的形式一一呈现,内容内聚性极强,例如性能优化、手把手实现链表、Cargo 和 Tokio 使用指南、async 异步编程、标准库解析、WASM 等等
- **内容索引**,作为一本工具书,优秀的索引能力非常重要,遗忘不可怕,找不到才可怕
- **规避陷阱和对抗编译器**,只有真的上手写过一长段时间 Rust 项目,才知道该如何规避常见的陷阱以及解决一些难搞的编译器错误,而本书将帮助你大大缩短这个过程,提前规避这些问题
- **[Cookbook](https://rusty.course.rs)**,涵盖多个应用场景的实战代码片段,程序员上网查询文件操作、正则解析、数据库操作是常事,没有人能记住所有代码,而 Cookbook 可解君忧,Ctrl + C/V 走天下
- **[配套练习题](https://github.com/sunface/rust-by-practice)**,像学习一门大学课程一样学习 Rust 是一种什么感觉?_Rust 语言圣经 + Rust 语言实战_ 双剑合璧,给你最极致的学习体验
总之在写作过程中我们始终铭记初心:为中国用户打造一门**全面的、深入的、持续更新的** Rust 教程。 新手用来入门,老手用来提高,高手用来提升生产力。
## 🏆 贡献者
非常感谢本教程的[所有贡献者](https://github.com/sunface/rust-course/graphs/contributors),正是有了你们,才有了现在的高质量 Rust 教程!
<br />
🏆
<table>
<tbody>
<tr>
<td align="center">
<a href="https://github.com/EluvK">
<img src="https://avatars.githubusercontent.com/u/36977935?v=4" width="160px" alt=""/>
<br />
<sub><b>EluvK</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/AllanDowney">
<img src="https://avatars.githubusercontent.com/u/82752697?v=4?s=100" width="160px" alt=""/>
<br />
<sub><b>AllanDowney</b></sub>
</a>
</td>
</tr>
</tbody>
</table>
<br />
🏅
<table>
<tbody>
<tr>
<td align="center">
<a href="https://github.com/SUN-LG">
<img src="https://avatars.githubusercontent.com/u/15073915?v=4" width="100px" alt=""/>
<br />
<sub><b>孙立刚</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/JesseAtSZ">
<img src="https://avatars.githubusercontent.com/u/35264598?v=4?s=100" width="100px" alt=""/>
<br />
<sub><b>JesseAtSZ</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/Rustln">
<img src="https://avatars.githubusercontent.com/u/100085326?v=4?s=100" width="100px" alt=""/>
<br />
<sub><b>Rustln</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/1132719438">
<img src="https://avatars.githubusercontent.com/u/10138791?v=4?s=100" width="100px" alt=""/>
<br />
<sub><b>1132719438</b></sub>
</a>
</td>
</tr>
</tbody>
</table>
## 创作感悟
截至目前,Rust 语言圣经已写了 170 余章,110 余万字,历经 800 多个小时,每一个章节都是手动写就,没有任何机翻和质量上的妥协( 相信深入阅读过的读者都能体会到这一点 )。
曾经有读者问过 "这么好的书为何要开源,而不是出版?",原因很简单:**只有完全开源才能完美地呈现出我想要的教学效果**。
总之,Rust 要在国内真正发展起来,必须得有一些追逐梦想的人在做着不计付出的事情,而我希望自己能贡献一份微薄之力。
但是要说完全无欲无求,那也是不可能的,看到项目多了一颗 🌟,那感觉...棒极了,因为它代表了读者的认可和称赞。
你们用指尖绘制的星空,那里繁星点点,每一颗都在鼓励着怀揣着开源梦想的程序员披荆斩棘、不断前行,不夸张的说,没有你们,开源世界就没有星光,自然也就不会有今天的开源盛世。
因此,**我恳请大家,如果觉得书还可以,就在你的指尖星空绘制一颗新的 🌟,指引我们继续砥砺前行**。这个人世间,因善意而美好。
最后,能通过开源在茫茫人海中与大家相识,这感觉真好 :D
## 开源协议
在开源版权上,我们选择了 [No License](https://choosealicense.com/no-permission/),这意味着读者可以随意的 fork 和阅读,但是**不能私下修改后再包装分发**,如果有这方面的需求,请联系我们,望理解。
## 借鉴的书籍
站在巨人的肩膀上,能帮我们看的更远,特此感谢以下巨人:
- [Rust Book](https://doc.rust-lang.org/book)
- [Rust nomicon](https://doc.rust-lang.org/nomicon/intro.html)
- [Async Rust](https://rust-lang.github.io/async-book/01_getting_started/01_chapter.html)
- 详细清单参见 [这里](./assets/writing-material/books.md)
因为它们绝大部分是支持 APACHE + MIT 双协议的,因此我们选择了遵循其中的 MIT 协议,并在这里统一对借鉴的书籍进行说明。
## 社区 & 读者交流
- 微信公众号: 扫描下面的二维码关注公众号
<img src="https://github.com/sunface/rust-course/blob/main/assets/studyrust公众号.png?raw=true" />
================================================
FILE: assets/CNAME
================================================
course.rs
================================================
FILE: assets/bigPicture.js
================================================
var BigPicture=function(){var t,n,e,o,i,r,a,c,p,s,l,d,u,f,m,b,g,h,x,v,y,w,_,T,k,M,S,L,E,A,H,z,I,C=[],D={},O="appendChild",N="createElement",V="removeChild";function W(){var n=t.getBoundingClientRect();return"transform:translate3D("+(n.left-(e.clientWidth-n.width)/2)+"px, "+(n.top-(e.clientHeight-n.height)/2)+"px, 0) scale3D("+t.clientWidth/o.clientWidth+", "+t.clientHeight/o.clientHeight+", 0)"}function q(t){var n=A.length-1;if(!u){if(t>0&&E===n||t<0&&!E){if(!I.loop)return j(i,""),void setTimeout(j,9,i,"animation:"+(t>0?"bpl":"bpf")+" .3s;transition:transform .35s");E=t>0?-1:n+1}if([(E=Math.max(0,Math.min(E+t,n)))-1,E,E+1].forEach(function(t){if(t=Math.max(0,Math.min(t,n)),!D[t]){var e=A[t].src,o=document[N]("IMG");o.addEventListener("load",F.bind(null,e)),o.src=e,D[t]=o}}),D[E].complete)return B(t);u=1,j(m,"opacity:.4;"),e[O](m),D[E].onload=function(){y&&B(t)},D[E].onerror=function(){A[E]={error:"Error loading image"},y&&B(t)}}}function B(n){u&&(e[V](m),u=0);var r=A[E];if(r.error)alert(r.error);else{var a=e.querySelector("img:last-of-type");j(i=o=D[E],"animation:"+(n>0?"bpfl":"bpfr")+" .35s;transition:transform .35s"),j(a,"animation:"+(n>0?"bpfol":"bpfor")+" .35s both"),e[O](i),r.el&&(t=r.el)}H.innerHTML=E+1+"/"+A.length,X(A[E].caption),M&&M([i,A[E]])}function P(){var t,n,e=.95*window.innerHeight,o=.95*window.innerWidth,i=I.dimensions||[1920,1080],r=i[0],a=i[1],p=a/r;p>e/o?n=(t=Math.min(a,e))/p:t=(n=Math.min(r,o))*p,c.style.cssText+="width:"+n+"px;height:"+t+"px;"}function G(t){~[1,4].indexOf(o.readyState)?(U(),setTimeout(function(){o.play()},99)):o.error?U(t):f=setTimeout(G,35,t)}function R(n){I.noLoader||(n&&j(m,"top:"+t.offsetTop+"px;left:"+t.offsetLeft+"px;height:"+t.clientHeight+"px;width:"+t.clientWidth+"px"),t.parentElement[n?O:V](m),u=n)}function X(t){t&&(g.innerHTML=t),j(b,"opacity:"+(t?"1;pointer-events:auto":"0"))}function F(t){!~C.indexOf(t)&&C.push(t)}function U(t){if(u&&R(),T&&T(),"string"==typeof t)return $(),I.onError?I.onError():alert("Error: The requested "+t+" could not be loaded.");_&&F(s),o.style.cssText+=W(),j(e,"opacity:1;pointer-events:auto"),k=setTimeout(k,410),v=1,y=!!A,setTimeout(function(){o.style.cssText+="transition:transform .35s;transform:none",h&&setTimeout(X,250,h)},60)}function Y(t){var n=t?t.target:e,i=[b,x,r,a,g,L,S,m];n.blur(),w||~i.indexOf(n)||(o.style.cssText+=W(),j(e,"pointer-events:auto"),setTimeout($,350),clearTimeout(k),v=0,w=1)}function $(){if((o===c?p:o).removeAttribute("src"),document.body[V](e),e[V](o),j(e,""),j(o,""),X(0),y){for(var t=e.querySelectorAll("img"),n=0;n<t.length;n++)e[V](t[n]);u&&e[V](m),e[V](H),y=A=0,D={},z||e[V](S),z||e[V](L),i.onload=U,i.onerror=U.bind(null,"image")}I.onClose&&I.onClose(),w=u=0}function j(t,n){t.style.cssText=n}return function(w){var D;return n||function(){var t;function s(t){var n=document[N]("button");return n.className=t,n.innerHTML='<svg viewBox="0 0 48 48"><path d="M28 24L47 5a3 3 0 1 0-4-4L24 20 5 1a3 3 0 1 0-4 4l19 19L1 43a3 3 0 1 0 4 4l19-19 19 19a3 3 0 0 0 4 0v-4L28 24z"/></svg>',n}function d(t,n){var e=document[N]("button");return e.className="bp-lr",e.innerHTML='<svg viewBox="0 0 129 129" height="70" fill="#fff"><path d="M88.6 121.3c.8.8 1.8 1.2 2.9 1.2s2.1-.4 2.9-1.2a4.1 4.1 0 0 0 0-5.8l-51-51 51-51a4.1 4.1 0 0 0-5.8-5.8l-54 53.9a4.1 4.1 0 0 0 0 5.8l54 53.9z"/></svg>',j(e,n),e.onclick=function(n){n.stopPropagation(),q(t)},e}var f=document[N]("STYLE");f.innerHTML="#bp_caption,#bp_container{bottom:0;left:0;right:0;position:fixed;opacity:0}#bp_container>*,#bp_loader{position:absolute;right:0;z-index:10}#bp_container,#bp_caption,#bp_container svg{pointer-events:none}#bp_container{top:0;z-index:9999;background:rgba(0,0,0,.7);opacity:0;transition:opacity .35s}#bp_loader{top:0;left:0;bottom:0;display:flex;align-items:center;cursor:wait;background:0;z-index:9}#bp_loader svg{width:50%;max-width:300px;max-height:50%;margin:auto;animation:bpturn 1s infinite linear}#bp_aud,#bp_container img,#bp_sv,#bp_vid{user-select:none;max-height:96%;max-width:96%;top:0;bottom:0;left:0;margin:auto;box-shadow:0 0 3em rgba(0,0,0,.4);z-index:-1}#bp_sv{background:#111}#bp_sv svg{width:66px}#bp_caption{font-size:.9em;padding:1.3em;background:rgba(15,15,15,.94);color:#fff;text-align:center;transition:opacity .3s}#bp_aud{width:650px;top:calc(50% - 20px);bottom:auto;box-shadow:none}#bp_count{left:0;right:auto;padding:14px;color:rgba(255,255,255,.7);font-size:22px;cursor:default}#bp_container button{position:absolute;border:0;outline:0;background:0;cursor:pointer;transition:all .1s}#bp_container>.bp-x{padding:0;height:41px;width:41px;border-radius:100%;top:8px;right:14px;opacity:.8;line-height:1}#bp_container>.bp-x:focus,#bp_container>.bp-x:hover{background:rgba(255,255,255,.2)}.bp-x svg,.bp-xc svg{height:21px;width:20px;fill:#fff;vertical-align:top;}.bp-xc svg{width:16px}#bp_container .bp-xc{left:2%;bottom:100%;padding:9px 20px 7px;background:#d04444;border-radius:2px 2px 0 0;opacity:.85}#bp_container .bp-xc:focus,#bp_container .bp-xc:hover{opacity:1}.bp-lr{top:50%;top:calc(50% - 130px);padding:99px 0;width:6%;background:0;border:0;opacity:.4;transition:opacity .1s}.bp-lr:focus,.bp-lr:hover{opacity:.8}@keyframes bpf{50%{transform:translatex(15px)}100%{transform:none}}@keyframes bpl{50%{transform:translatex(-15px)}100%{transform:none}}@keyframes bpfl{0%{opacity:0;transform:translatex(70px)}100%{opacity:1;transform:none}}@keyframes bpfr{0%{opacity:0;transform:translatex(-70px)}100%{opacity:1;transform:none}}@keyframes bpfol{0%{opacity:1;transform:none}100%{opacity:0;transform:translatex(-70px)}}@keyframes bpfor{0%{opacity:1;transform:none}100%{opacity:0;transform:translatex(70px)}}@keyframes bpturn{0%{transform:none}100%{transform:rotate(360deg)}}@media (max-width:600px){.bp-lr{font-size:15vw}}",document.head[O](f),(e=document[N]("DIV")).id="bp_container",e.onclick=Y,l=s("bp-x"),e[O](l),"ontouchstart"in window&&(z=1,e.ontouchstart=function(n){var e=n.changedTouches;t=e[0].pageX},e.ontouchmove=function(t){t.preventDefault()},e.ontouchend=function(n){var e=n.changedTouches;if(y){var o=e[0].pageX-t;o<-30&&q(1),o>30&&q(-1)}}),i=document[N]("IMG"),(r=document[N]("VIDEO")).id="bp_vid",r.setAttribute("playsinline",1),r.controls=1,r.loop=1,(a=document[N]("audio")).id="bp_aud",a.controls=1,a.loop=1,(H=document[N]("span")).id="bp_count",(b=document[N]("DIV")).id="bp_caption",(x=s("bp-xc")).onclick=X.bind(null,0),b[O](x),g=document[N]("SPAN"),b[O](g),e[O](b),S=d(1,"transform:scalex(-1)"),L=d(-1,"left:0;right:auto"),(m=document[N]("DIV")).id="bp_loader",m.innerHTML='<svg viewbox="0 0 32 32" fill="#fff" opacity=".8"><path d="M16 0a16 16 0 0 0 0 32 16 16 0 0 0 0-32m0 4a12 12 0 0 1 0 24 12 12 0 0 1 0-24" fill="#000" opacity=".5"/><path d="M16 0a16 16 0 0 1 16 16h-4A12 12 0 0 0 16 4z"/></svg>',(c=document[N]("DIV")).id="bp_sv",(p=document[N]("IFRAME")).setAttribute("allowfullscreen",1),p.allow="autoplay; fullscreen",p.onload=function(){return c[V](m)},j(p,"border:0;position:absolute;height:100%;width:100%;left:0;top:0"),c[O](p),i.onload=U,i.onerror=U.bind(null,"image"),window.addEventListener("resize",function(){y||u&&R(1),o===c&&P()}),document.addEventListener("keyup",function(t){var n=t.keyCode;27===n&&v&&Y(),y&&(39===n&&q(1),37===n&&q(-1),38===n&&q(10),40===n&&q(-10))}),document.addEventListener("keydown",function(t){y&&~[37,38,39,40].indexOf(t.keyCode)&&t.preventDefault()}),document.addEventListener("focus",function(t){v&&!e.contains(t.target)&&(t.stopPropagation(),l.focus())},1),n=1}(),u&&(clearTimeout(f),$()),I=w,d=w.ytSrc||w.vimeoSrc,T=w.animationStart,k=w.animationEnd,M=w.onChangeImage,_=0,h=(t=w.el).getAttribute("data-caption"),w.gallery?function(n,r){var a=I.galleryAttribute||"data-bp";if(Array.isArray(n))A=n,h=n[E=r||0].caption;else{var c=(A=[].slice.call("string"==typeof n?document.querySelectorAll(n+" ["+a+"]"):n)).indexOf(t);E=0===r||r?r:-1!==c?c:0,A=A.map(function(t){return{el:t,src:t.getAttribute(a),caption:t.getAttribute("data-caption")}})}_=1,!~C.indexOf(s=A[E].src)&&R(1),A.length>1?(e[O](H),H.innerHTML=E+1+"/"+A.length,z||(e[O](S),e[O](L))):A=0,(o=i).src=s}(w.gallery,w.position):d||w.iframeSrc?(o=c,I.ytSrc?W="https://www.youtube.com/embed/"+d+"?html5=1&rel=0&playsinline=1&autoplay=1":I.vimeoSrc?W="https://player.vimeo.com/video/"+d+"?autoplay=1":I.iframeSrc&&(W=I.iframeSrc),j(m,""),c[O](m),p.src=W,P(),setTimeout(U,9)):w.imgSrc?(_=1,!~C.indexOf(s=w.imgSrc)&&R(1),(o=i).src=s):w.audio?(R(1),(o=a).src=w.audio,G("audio file")):w.vidSrc?(R(1),w.dimensions&&j(r,"width:"+w.dimensions[0]+"px"),D=w.vidSrc,Array.isArray(D)?(o=r.cloneNode(),D.forEach(function(t){var n=document[N]("SOURCE");n.src=t,n.type="video/"+t.match(/.(\w+)$/)[1],o[O](n)})):(o=r).src=D,G("video")):(o=i).src="IMG"===t.tagName?t.src:window.getComputedStyle(t).backgroundImage.replace(/^url|[(|)|'|"]/g,""),e[O](o),document.body[O](e),{close:Y,next:function(){return q(1)},prev:function(){return q(-1)}};var W}}();
================================================
FILE: assets/custom.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=" + 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-course");
script.setAttribute("data-repo-id", "MDEwOlJlcG9zaXRvcnkxNDM4MjIwNjk=");
script.setAttribute("data-category", "章节评论区");
script.setAttribute("data-category-id", "DIC_kwDOCJKM9c4COQcP");
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);
// 预先加载评论会更好,这样用户读到那边时,评论就加载好了
// script.setAttribute("data-loading", "lazy");
document.getElementById("giscus-container").appendChild(script);
};
window.addEventListener('load', initAll);
================================================
FILE: assets/rustlings-zh/.all-contributorsrc
================================================
{
"files": [
"README.md"
],
"imageSize": 100,
"commit": false,
"contributors": [
{
"login": "carols10cents",
"name": "Carol (Nichols || Goulding)",
"avatar_url": "https://avatars2.githubusercontent.com/u/193874?v=4",
"profile": "http://carol-nichols.com",
"contributions": [
"code",
"content"
]
},
{
"login": "QuietMisdreavus",
"name": "QuietMisdreavus",
"avatar_url": "https://avatars2.githubusercontent.com/u/5217170?v=4",
"profile": "https://twitter.com/QuietMisdreavus",
"contributions": [
"code",
"content"
]
},
{
"login": "robertlugg",
"name": "Robert M Lugg",
"avatar_url": "https://avatars0.githubusercontent.com/u/6054540?v=4",
"profile": "https://github.com/robertlugg",
"contributions": [
"content"
]
},
{
"login": "hynek",
"name": "Hynek Schlawack",
"avatar_url": "https://avatars3.githubusercontent.com/u/41240?v=4",
"profile": "https://hynek.me/about/",
"contributions": [
"code"
]
},
{
"login": "spacekookie",
"name": "Katharina Fey",
"avatar_url": "https://avatars0.githubusercontent.com/u/7669898?v=4",
"profile": "https://spacekookie.de",
"contributions": [
"code"
]
},
{
"login": "lukabavdaz",
"name": "lukabavdaz",
"avatar_url": "https://avatars0.githubusercontent.com/u/9624558?v=4",
"profile": "https://github.com/lukabavdaz",
"contributions": [
"code",
"content"
]
},
{
"login": "evestera",
"name": "Erik Vesteraas",
"avatar_url": "https://avatars2.githubusercontent.com/u/4187449?v=4",
"profile": "http://vestera.as",
"contributions": [
"code"
]
},
{
"login": "Delet0r",
"name": "delet0r",
"avatar_url": "https://avatars1.githubusercontent.com/u/23195618?v=4",
"profile": "https://github.com/Delet0r",
"contributions": [
"code"
]
},
{
"login": "shaunbennett",
"name": "Shaun Bennett",
"avatar_url": "https://avatars1.githubusercontent.com/u/10522375?v=4",
"profile": "http://phinary.ca",
"contributions": [
"code"
]
},
{
"login": "abagshaw",
"name": "Andrew Bagshaw",
"avatar_url": "https://avatars2.githubusercontent.com/u/8594541?v=4",
"profile": "https://github.com/abagshaw",
"contributions": [
"code"
]
},
{
"login": "kisom",
"name": "Kyle Isom",
"avatar_url": "https://avatars2.githubusercontent.com/u/175578?v=4",
"profile": "https://ai6ua.net/",
"contributions": [
"code"
]
},
{
"login": "ColinPitrat",
"name": "Colin Pitrat",
"avatar_url": "https://avatars3.githubusercontent.com/u/1541863?v=4",
"profile": "https://github.com/ColinPitrat",
"contributions": [
"code"
]
},
{
"login": "zacanger",
"name": "Zac Anger",
"avatar_url": "https://avatars3.githubusercontent.com/u/12520493?v=4",
"profile": "https://zacanger.com",
"contributions": [
"code"
]
},
{
"login": "mgeier",
"name": "Matthias Geier",
"avatar_url": "https://avatars1.githubusercontent.com/u/705404?v=4",
"profile": "https://github.com/mgeier",
"contributions": [
"code"
]
},
{
"login": "cjpearce",
"name": "Chris Pearce",
"avatar_url": "https://avatars1.githubusercontent.com/u/3453268?v=4",
"profile": "https://github.com/cjpearce",
"contributions": [
"code"
]
},
{
"login": "yvan-sraka",
"name": "Yvan Sraka",
"avatar_url": "https://avatars2.githubusercontent.com/u/705213?v=4",
"profile": "https://yvan-sraka.github.io",
"contributions": [
"code"
]
},
{
"login": "dendi239",
"name": "Denys Smirnov",
"avatar_url": "https://avatars3.githubusercontent.com/u/16478650?v=4",
"profile": "https://github.com/dendi239",
"contributions": [
"code"
]
},
{
"login": "eddyp",
"name": "eddyp",
"avatar_url": "https://avatars2.githubusercontent.com/u/123772?v=4",
"profile": "https://github.com/eddyp",
"contributions": [
"code"
]
},
{
"login": "briankung",
"name": "Brian Kung",
"avatar_url": "https://avatars1.githubusercontent.com/u/2836167?v=4",
"profile": "http://about.me/BrianKung",
"contributions": [
"code",
"content"
]
},
{
"login": "miller-time",
"name": "Russell",
"avatar_url": "https://avatars3.githubusercontent.com/u/281039?v=4",
"profile": "https://rcousineau.gitlab.io",
"contributions": [
"code"
]
},
{
"login": "danwilhelm",
"name": "Dan Wilhelm",
"avatar_url": "https://avatars3.githubusercontent.com/u/6137185?v=4",
"profile": "http://danwilhelm.com",
"contributions": [
"doc"
]
},
{
"login": "Jesse-Cameron",
"name": "Jesse",
"avatar_url": "https://avatars3.githubusercontent.com/u/3723654?v=4",
"profile": "https://github.com/Jesse-Cameron",
"contributions": [
"code",
"content"
]
},
{
"login": "MrFroop",
"name": "Fredrik Jambrén",
"avatar_url": "https://avatars3.githubusercontent.com/u/196700?v=4",
"profile": "https://github.com/MrFroop",
"contributions": [
"code"
]
},
{
"login": "petemcfarlane",
"name": "Pete McFarlane",
"avatar_url": "https://avatars3.githubusercontent.com/u/3472717?v=4",
"profile": "https://github.com/petemcfarlane",
"contributions": [
"content"
]
},
{
"login": "nkanderson",
"name": "nkanderson",
"avatar_url": "https://avatars0.githubusercontent.com/u/4128825?v=4",
"profile": "https://github.com/nkanderson",
"contributions": [
"code",
"content"
]
},
{
"login": "ajaxm",
"name": "Ajax M",
"avatar_url": "https://avatars0.githubusercontent.com/u/13360138?v=4",
"profile": "https://github.com/ajaxm",
"contributions": [
"doc"
]
},
{
"login": "Dylnuge",
"name": "Dylan Nugent",
"avatar_url": "https://avatars2.githubusercontent.com/u/118624?v=4",
"profile": "https://dylnuge.com",
"contributions": [
"content"
]
},
{
"login": "vyaslav",
"name": "vyaslav",
"avatar_url": "https://avatars0.githubusercontent.com/u/1385427?v=4",
"profile": "https://github.com/vyaslav",
"contributions": [
"code",
"content"
]
},
{
"login": "gdoenlen",
"name": "George",
"avatar_url": "https://avatars1.githubusercontent.com/u/17297466?v=4",
"profile": "https://join.sfxd.org",
"contributions": [
"code"
]
},
{
"login": "nyxtom",
"name": "Thomas Holloway",
"avatar_url": "https://avatars2.githubusercontent.com/u/222763?v=4",
"profile": "https://github.com/nyxtom",
"contributions": [
"code",
"content"
]
},
{
"login": "workingjubilee",
"name": "Jubilee",
"avatar_url": "https://avatars1.githubusercontent.com/u/46493976?v=4",
"profile": "https://github.com/workingjubilee",
"contributions": [
"code"
]
},
{
"login": "WofWca",
"name": "WofWca",
"avatar_url": "https://avatars1.githubusercontent.com/u/39462442?v=4",
"profile": "https://github.com/WofWca",
"contributions": [
"code"
]
},
{
"login": "jrvidal",
"name": "Roberto Vidal",
"avatar_url": "https://avatars0.githubusercontent.com/u/1636604?v=4",
"profile": "https://github.com/jrvidal",
"contributions": [
"code",
"doc",
"ideas",
"maintenance"
]
},
{
"login": "jensim",
"name": "Jens",
"avatar_url": "https://avatars0.githubusercontent.com/u/3663856?v=4",
"profile": "https://github.com/jensim",
"contributions": [
"doc"
]
},
{
"login": "rahatarmanahmed",
"name": "Rahat Ahmed",
"avatar_url": "https://avatars3.githubusercontent.com/u/3174006?v=4",
"profile": "http://rahatah.me/d",
"contributions": [
"doc"
]
},
{
"login": "AbdouSeck",
"name": "Abdou Seck",
"avatar_url": "https://avatars2.githubusercontent.com/u/6490055?v=4",
"profile": "https://github.com/AbdouSeck",
"contributions": [
"code",
"content",
"review"
]
},
{
"login": "codehearts",
"name": "Katie",
"avatar_url": "https://avatars0.githubusercontent.com/u/2885412?v=4",
"profile": "https://codehearts.com",
"contributions": [
"code"
]
},
{
"login": "Socratides",
"name": "Socrates",
"avatar_url": "https://avatars3.githubusercontent.com/u/27732983?v=4",
"profile": "https://github.com/Socratides",
"contributions": [
"doc"
]
},
{
"login": "gnodarse",
"name": "gnodarse",
"avatar_url": "https://avatars3.githubusercontent.com/u/46761795?v=4",
"profile": "https://github.com/gnodarse",
"contributions": [
"content"
]
},
{
"login": "harrisonmetz",
"name": "Harrison Metzger",
"avatar_url": "https://avatars1.githubusercontent.com/u/7883408?v=4",
"profile": "https://github.com/harrisonmetz",
"contributions": [
"code"
]
},
{
"login": "TorbenJ",
"name": "Torben Jonas",
"avatar_url": "https://avatars2.githubusercontent.com/u/9077102?v=4",
"profile": "https://github.com/TorbenJ",
"contributions": [
"code",
"content"
]
},
{
"login": "pbx",
"name": "Paul Bissex",
"avatar_url": "https://avatars0.githubusercontent.com/u/641?v=4",
"profile": "http://paulbissex.com/",
"contributions": [
"doc"
]
},
{
"login": "sjmann",
"name": "Steven Mann",
"avatar_url": "https://avatars0.githubusercontent.com/u/6589896?v=4",
"profile": "https://github.com/sjmann",
"contributions": [
"code",
"content"
]
},
{
"login": "Tarnadas",
"name": "Mario Reder",
"avatar_url": "https://avatars2.githubusercontent.com/u/5855071?v=4",
"profile": "https://smmdb.net/",
"contributions": [
"code",
"content"
]
},
{
"login": "sl4m",
"name": "skim",
"avatar_url": "https://avatars0.githubusercontent.com/u/47347?v=4",
"profile": "https://keybase.io/skim",
"contributions": [
"code"
]
},
{
"login": "sanjaykdragon",
"name": "Sanjay K",
"avatar_url": "https://avatars1.githubusercontent.com/u/10261698?v=4",
"profile": "https://github.com/sanjaykdragon",
"contributions": [
"code",
"content"
]
},
{
"login": "crodjer",
"name": "Rohan Jain",
"avatar_url": "https://avatars1.githubusercontent.com/u/343499?v=4",
"profile": "http://www.rohanjain.in",
"contributions": [
"code"
]
},
{
"login": "saidaspen",
"name": "Said Aspen",
"avatar_url": "https://avatars1.githubusercontent.com/u/7727687?v=4",
"profile": "https://www.saidaspen.se",
"contributions": [
"code",
"content"
]
},
{
"login": "uce",
"name": "Ufuk Celebi",
"avatar_url": "https://avatars3.githubusercontent.com/u/1756620?v=4",
"profile": "https://github.com/uce",
"contributions": [
"code"
]
},
{
"login": "lebedevsergey",
"name": "lebedevsergey",
"avatar_url": "https://avatars2.githubusercontent.com/u/7325764?v=4",
"profile": "https://github.com/lebedevsergey",
"contributions": [
"doc"
]
},
{
"login": "avrong",
"name": "Aleksei Trifonov",
"avatar_url": "https://avatars2.githubusercontent.com/u/6342851?v=4",
"profile": "https://github.com/avrong",
"contributions": [
"content"
]
},
{
"login": "Darrenmeehan",
"name": "Darren Meehan",
"avatar_url": "https://avatars2.githubusercontent.com/u/411136?v=4",
"profile": "https://drn.ie",
"contributions": [
"content"
]
},
{
"login": "jihchi",
"name": "Jihchi Lee",
"avatar_url": "https://avatars1.githubusercontent.com/u/87983?v=4",
"profile": "https://github.com/jihchi",
"contributions": [
"content"
]
},
{
"login": "bertonha",
"name": "Christofer Bertonha",
"avatar_url": "https://avatars3.githubusercontent.com/u/1225902?v=4",
"profile": "https://github.com/bertonha",
"contributions": [
"content"
]
},
{
"login": "apatniv",
"name": "Vivek Bharath Akupatni",
"avatar_url": "https://avatars2.githubusercontent.com/u/22565917?v=4",
"profile": "https://github.com/apatniv",
"contributions": [
"code",
"test"
]
},
{
"login": "DiD92",
"name": "Dídac Sementé Fernández",
"avatar_url": "https://avatars3.githubusercontent.com/u/6002416?v=4",
"profile": "https://github.com/DiD92",
"contributions": [
"code",
"content"
]
},
{
"login": "wrobstory",
"name": "Rob Story",
"avatar_url": "https://avatars3.githubusercontent.com/u/2601457?v=4",
"profile": "https://github.com/wrobstory",
"contributions": [
"code"
]
},
{
"login": "siobhanjacobson",
"name": "Siobhan Jacobson",
"avatar_url": "https://avatars2.githubusercontent.com/u/28983835?v=4",
"profile": "https://github.com/siobhanjacobson",
"contributions": [
"code"
]
},
{
"login": "EvanCarroll",
"name": "Evan Carroll",
"avatar_url": "https://avatars2.githubusercontent.com/u/19922?v=4",
"profile": "https://www.linkedin.com/in/evancarroll/",
"contributions": [
"content"
]
},
{
"login": "jmahmood",
"name": "Jawaad Mahmood",
"avatar_url": "https://avatars3.githubusercontent.com/u/95606?v=4",
"profile": "http://www.jawaadmahmood.com",
"contributions": [
"content"
]
},
{
"login": "GaurangTandon",
"name": "Gaurang Tandon",
"avatar_url": "https://avatars1.githubusercontent.com/u/6308683?v=4",
"profile": "https://github.com/GaurangTandon",
"contributions": [
"content"
]
},
{
"login": "dev-cyprium",
"name": "Stefan Kupresak",
"avatar_url": "https://avatars1.githubusercontent.com/u/6002628?v=4",
"profile": "https://github.com/dev-cyprium",
"contributions": [
"content"
]
},
{
"login": "greg-el",
"name": "Greg Leonard",
"avatar_url": "https://avatars3.githubusercontent.com/u/45019882?v=4",
"profile": "https://github.com/greg-el",
"contributions": [
"content"
]
},
{
"login": "ryanpcmcquen",
"name": "Ryan McQuen",
"avatar_url": "https://avatars3.githubusercontent.com/u/772937?v=4",
"profile": "https://ryanpcmcquen.org",
"contributions": [
"code"
]
},
{
"login": "AnnikaCodes",
"name": "Annika",
"avatar_url": "https://avatars3.githubusercontent.com/u/56906084?v=4",
"profile": "https://github.com/AnnikaCodes",
"contributions": [
"review"
]
},
{
"login": "darnuria",
"name": "Axel Viala",
"avatar_url": "https://avatars1.githubusercontent.com/u/2827553?v=4",
"profile": "https://darnuria.eu",
"contributions": [
"code"
]
},
{
"login": "sazid",
"name": "Mohammed Sazid Al Rashid",
"avatar_url": "https://avatars1.githubusercontent.com/u/2370167?v=4",
"profile": "https://sazid.github.io",
"contributions": [
"content",
"code"
]
},
{
"login": "seeplusplus",
"name": "Caleb Webber",
"avatar_url": "https://avatars1.githubusercontent.com/u/17479099?v=4",
"profile": "https://codingthemsoftly.com",
"contributions": [
"maintenance"
]
},
{
"login": "pcn",
"name": "Peter N",
"avatar_url": "https://avatars2.githubusercontent.com/u/1056756?v=4",
"profile": "https://github.com/pcn",
"contributions": [
"maintenance"
]
},
{
"login": "seancad",
"name": "seancad",
"avatar_url": "https://avatars1.githubusercontent.com/u/47405611?v=4",
"profile": "https://github.com/seancad",
"contributions": [
"maintenance"
]
},
{
"login": "wsh",
"name": "Will Hayworth",
"avatar_url": "https://avatars3.githubusercontent.com/u/181174?v=4",
"profile": "http://willhayworth.com",
"contributions": [
"content"
]
},
{
"login": "chrizel",
"name": "Christian Zeller",
"avatar_url": "https://avatars3.githubusercontent.com/u/20802?v=4",
"profile": "https://github.com/chrizel",
"contributions": [
"content"
]
},
{
"login": "jfchevrette",
"name": "Jean-Francois Chevrette",
"avatar_url": "https://avatars.githubusercontent.com/u/3001?v=4",
"profile": "https://github.com/jfchevrette",
"contributions": [
"content",
"code"
]
},
{
"login": "jbaber",
"name": "John Baber-Lucero",
"avatar_url": "https://avatars.githubusercontent.com/u/1908117?v=4",
"profile": "https://github.com/jbaber",
"contributions": [
"content"
]
},
{
"login": "tal-zvon",
"name": "Tal",
"avatar_url": "https://avatars.githubusercontent.com/u/3195851?v=4",
"profile": "https://github.com/tal-zvon",
"contributions": [
"content"
]
},
{
"login": "apogeeoak",
"name": "apogeeoak",
"avatar_url": "https://avatars.githubusercontent.com/u/59737221?v=4",
"profile": "https://github.com/apogeeoak",
"contributions": [
"content",
"code"
]
},
{
"login": "Crell",
"name": "Larry Garfield",
"avatar_url": "https://avatars.githubusercontent.com/u/254863?v=4",
"profile": "http://www.garfieldtech.com/",
"contributions": [
"content"
]
},
{
"login": "circumspect",
"name": "circumspect",
"avatar_url": "https://avatars.githubusercontent.com/u/40770208?v=4",
"profile": "https://github.com/circumspect",
"contributions": [
"content"
]
},
{
"login": "cjwyett",
"name": "Cyrus Wyett",
"avatar_url": "https://avatars.githubusercontent.com/u/34195737?v=4",
"profile": "https://github.com/cjwyett",
"contributions": [
"content"
]
},
{
"login": "cadolphs",
"name": "cadolphs",
"avatar_url": "https://avatars.githubusercontent.com/u/13894820?v=4",
"profile": "https://github.com/cadolphs",
"contributions": [
"code"
]
},
{
"login": "hpwxf",
"name": "Pascal H.",
"avatar_url": "https://avatars.githubusercontent.com/u/26146722?v=4",
"profile": "https://www.haveneer.com",
"contributions": [
"content"
]
},
{
"login": "chapeupreto",
"name": "Rod Elias",
"avatar_url": "https://avatars.githubusercontent.com/u/834048?v=4",
"profile": "https://twitter.com/chapeupreto",
"contributions": [
"content"
]
},
{
"login": "blerchy",
"name": "Matt Lebl",
"avatar_url": "https://avatars.githubusercontent.com/u/2555355?v=4",
"profile": "https://github.com/blerchy",
"contributions": [
"code"
]
},
{
"login": "flakolefluk",
"name": "Ignacio Le Fluk",
"avatar_url": "https://avatars.githubusercontent.com/u/11986564?v=4",
"profile": "http://flakolefluk.dev",
"contributions": [
"content"
]
},
{
"login": "tlyu",
"name": "Taylor Yu",
"avatar_url": "https://avatars.githubusercontent.com/u/431873?v=4",
"profile": "https://github.com/tlyu",
"contributions": [
"code",
"content"
]
},
{
"login": "Zerotask",
"name": "Patrick Hintermayer",
"avatar_url": "https://avatars.githubusercontent.com/u/20150243?v=4",
"profile": "https://zerotask.github.io",
"contributions": [
"code"
]
},
{
"login": "arthas168",
"name": "Pete Pavlovski",
"avatar_url": "https://avatars.githubusercontent.com/u/32264020?v=4",
"profile": "https://petkopavlovski.com/",
"contributions": [
"content"
]
},
{
"login": "k12ish",
"name": "k12ish",
"avatar_url": "https://avatars.githubusercontent.com/u/45272873?v=4",
"profile": "https://github.com/k12ish",
"contributions": [
"content"
]
},
{
"login": "hongshaoyang",
"name": "Shao Yang Hong",
"avatar_url": "https://avatars.githubusercontent.com/u/19281800?v=4",
"profile": "https://github.com/hongshaoyang",
"contributions": [
"content"
]
},
{
"login": "bmacer",
"name": "Brandon Macer",
"avatar_url": "https://avatars.githubusercontent.com/u/13931806?v=4",
"profile": "https://github.com/bmacer",
"contributions": [
"content"
]
},
{
"login": "stoiandan",
"name": "Stoian Dan",
"avatar_url": "https://avatars.githubusercontent.com/u/10388612?v=4",
"profile": "https://github.com/stoiandan",
"contributions": [
"content"
]
},
{
"login": "PiDelport",
"name": "Pi Delport",
"avatar_url": "https://avatars.githubusercontent.com/u/630271?v=4",
"profile": "https://about.me/pjdelport",
"contributions": [
"content"
]
},
{
"login": "sateeshkumarb",
"name": "Sateesh ",
"avatar_url": "https://avatars.githubusercontent.com/u/429263?v=4",
"profile": "https://github.com/sateeshkumarb",
"contributions": [
"code",
"content"
]
},
{
"login": "kayuapi",
"name": "ZC",
"avatar_url": "https://avatars.githubusercontent.com/u/10304328?v=4",
"profile": "https://github.com/kayuapi",
"contributions": [
"content"
]
},
{
"login": "hyperparabolic",
"name": "hyperparabolic",
"avatar_url": "https://avatars.githubusercontent.com/u/12348474?v=4",
"profile": "https://github.com/hyperparabolic",
"contributions": [
"code"
]
},
{
"login": "kolbma",
"name": "arlecchino",
"avatar_url": "https://avatars.githubusercontent.com/u/5228369?v=4",
"profile": "https://www.net4visions.at",
"contributions": [
"doc"
]
},
{
"login": "jazzplato",
"name": "Richthofen",
"avatar_url": "https://avatars.githubusercontent.com/u/7576730?v=4",
"profile": "https://richthofen.io/",
"contributions": [
"code"
]
},
{
"login": "cseltol",
"name": "Ivan Nerazumov",
"avatar_url": "https://avatars.githubusercontent.com/u/64264529?v=4",
"profile": "https://github.com/cseltol",
"contributions": [
"doc"
]
},
{
"login": "lauralindzey",
"name": "lauralindzey",
"avatar_url": "https://avatars.githubusercontent.com/u/65185744?v=4",
"profile": "https://github.com/lauralindzey",
"contributions": [
"doc"
]
},
{
"login": "sinharaksh1t",
"name": "Rakshit Sinha",
"avatar_url": "https://avatars.githubusercontent.com/u/28585848?v=4",
"profile": "https://github.com/sinharaksh1t",
"contributions": [
"content"
]
},
{
"login": "dbednar230",
"name": "Damian",
"avatar_url": "https://avatars.githubusercontent.com/u/54457902?v=4",
"profile": "https://github.com/dbednar230",
"contributions": [
"content"
]
},
{
"login": "benarmstead",
"name": "Ben Armstead",
"avatar_url": "https://avatars.githubusercontent.com/u/70973680?v=4",
"profile": "https://benarmstead.co.uk",
"contributions": [
"code"
]
},
{
"login": "anuk909",
"name": "anuk909",
"avatar_url": "https://avatars.githubusercontent.com/u/34924662?v=4",
"profile": "https://github.com/anuk909",
"contributions": [
"content",
"code"
]
},
{
"login": "granddaifuku",
"name": "granddaifuku",
"avatar_url": "https://avatars.githubusercontent.com/u/49578068?v=4",
"profile": "https://granddaifuku.com/",
"contributions": [
"content"
]
},
{
"login": "Weilet",
"name": "Weilet",
"avatar_url": "https://avatars.githubusercontent.com/u/32561597?v=4",
"profile": "https://weilet.me",
"contributions": [
"content"
]
},
{
"login": "Millione",
"name": "LIU JIE",
"avatar_url": "https://avatars.githubusercontent.com/u/38575932?v=4",
"profile": "https://github.com/Millione",
"contributions": [
"content"
]
},
{
"login": "abusch",
"name": "Antoine Büsch",
"avatar_url": "https://avatars.githubusercontent.com/u/506344?v=4",
"profile": "https://github.com/abusch",
"contributions": [
"code"
]
},
{
"login": "frogtd",
"name": "frogtd",
"avatar_url": "https://avatars.githubusercontent.com/u/31412003?v=4",
"profile": "https://frogtd.com/",
"contributions": [
"content"
]
},
{
"login": "EmisonLu",
"name": "Zhenghao Lu",
"avatar_url": "https://avatars.githubusercontent.com/u/54395432?v=4",
"profile": "https://github.com/EmisonLu",
"contributions": [
"content"
]
},
{
"login": "fredr",
"name": "Fredrik Enestad",
"avatar_url": "https://avatars.githubusercontent.com/u/762956?v=4",
"profile": "https://soundtrackyourbrand.com",
"contributions": [
"content"
]
},
{
"login": "xuesongbj",
"name": "xuesong",
"avatar_url": "https://avatars.githubusercontent.com/u/18476085?v=4",
"profile": "http://xuesong.pydevops.com",
"contributions": [
"content"
]
},
{
"login": "MpdWalsh",
"name": "Michael Walsh",
"avatar_url": "https://avatars.githubusercontent.com/u/48160144?v=4",
"profile": "https://github.com/MpdWalsh",
"contributions": [
"code"
]
}
],
"contributorsPerLine": 8,
"projectName": "rustlings",
"projectOwner": "rust-lang",
"repoType": "github",
"repoHost": "https://github.com",
"skipCi": true
}
================================================
FILE: assets/rustlings-zh/.clog.toml
================================================
[clog]
repository = "https://github.com/rust-lang/rustlings"
changelog = "CHANGELOG.md"
================================================
FILE: assets/rustlings-zh/.editorconfig
================================================
root = true
[*.rs]
end_of_line = lf
insert_final_newfile = true
indent_style = space
indent_size = 4
================================================
FILE: assets/rustlings-zh/.gitignore
================================================
*.swp
target/
**/*.rs.bk
.DS_Store
*.pdb
exercises/clippy/Cargo.toml
exercises/clippy/Cargo.lock
.idea/
.vscode
*.iml
================================================
FILE: assets/rustlings-zh/.gitpod.yml
================================================
tasks:
- init: /workspace/rustlings/install.sh
command: /workspace/.cargo/bin/rustlings watch
vscode:
extensions:
- rust-lang.rust@0.7.8:CvNqMTgDdt3UXt+6BCDTVg==
================================================
FILE: assets/rustlings-zh/.replit
================================================
language = "rust"
run = "[ -x ~/.cargo/bin/rustlings ] && ~/.cargo/bin/rustlings watch || ./install.sh"
================================================
FILE: assets/rustlings-zh/CHANGELOG.md
================================================
<a name="4.6.0"></a>
## 4.6.0 (2021-09-25)
#### Features
* add advanced_errs2 ([abd6b70c](https://github.com/rust-lang/rustlings/commit/abd6b70c72dc6426752ff41f09160b839e5c449e))
* add advanced_errs1 ([882d535b](https://github.com/rust-lang/rustlings/commit/882d535ba8628d5e0b37e8664b3e2f26260b2671))
* Add a farewell message when quitting `watch` ([1caef0b4](https://github.com/rust-lang/rustlings/commit/1caef0b43494c8b8cdd6c9260147e70d510f1aca))
* add more watch commands ([a7dc080b](https://github.com/rust-lang/rustlings/commit/a7dc080b95e49146fbaafe6922a6de2f8cb1582a), closes [#842](https://github.com/rust-lang/rustlings/issues/842))
* **modules:** update exercises, add modules3 (#822) ([dfd2fab4](https://github.com/rust-lang/rustlings/commit/dfd2fab4f33d1bf59e2e5ee03123c0c9a67a9481))
* **quiz1:** add default function name in comment (#838) ([0a11bad7](https://github.com/rust-lang/rustlings/commit/0a11bad71402b5403143d642f439f57931278c07))
#### Bug Fixes
* Correct small typo in exercises/conversions/from_str.rs ([86cc8529](https://github.com/rust-lang/rustlings/commit/86cc85295ae36948963ae52882e285d7e3e29323))
* **cli:** typo in exercise.rs (#848) ([06d5c097](https://github.com/rust-lang/rustlings/commit/06d5c0973a3dffa3c6c6f70acb775d4c6630323c))
* **from_str, try_from_into:** custom error types ([2dc93cad](https://github.com/rust-lang/rustlings/commit/2dc93caddad43821743e4903d89b355df58d7a49))
* **modules2:** fix typo (#835) ([1c3beb0a](https://github.com/rust-lang/rustlings/commit/1c3beb0a59178c950dc05fe8ee2346b017429ae0))
* **move_semantics5:**
* change &mut *y to &mut x (#814) ([d75759e8](https://github.com/rust-lang/rustlings/commit/d75759e829fdcd64ef071cf4b6eae2a011a7718b))
* Clarify instructions ([df25684c](https://github.com/rust-lang/rustlings/commit/df25684cb79f8413915e00b5efef29369849cef1))
* **quiz1:** Fix inconsistent wording (#826) ([03131a3d](https://github.com/rust-lang/rustlings/commit/03131a3d35d9842598150f9da817f7cc26e2669a))
<a name="4.5.0"></a>
## 4.5.0 (2021-07-07)
#### Features
* Add move_semantics5 exercise. (#746) ([399ab328](https://github.com/rust-lang/rustlings/commit/399ab328d8d407265c09563aa4ef4534b2503ff2))
* **cli:** Add "next" to run the next unsolved exercise. (#785) ([d20e413a](https://github.com/rust-lang/rustlings/commit/d20e413a68772cd493561f2651cf244e822b7ca5))
#### Bug Fixes
* rename result1 to errors4 ([50ab289d](https://github.com/rust-lang/rustlings/commit/50ab289da6b9eb19a7486c341b00048c516b88c0))
* move_semantics5 hints ([1b858285](https://github.com/rust-lang/rustlings/commit/1b85828548f46f58b622b5e0c00f8c989f928807))
* remove trailing whitespaces from iterators1 ([4d4fa774](https://github.com/rust-lang/rustlings/commit/4d4fa77459392acd3581c6068aa8be9a02de12fc))
* add hints to generics1 and generics2 exercises ([31457940](https://github.com/rust-lang/rustlings/commit/31457940846b3844d78d4a4d2b074bc8d6aaf1eb))
* remove trailing whitespace ([d9b69bd1](https://github.com/rust-lang/rustlings/commit/d9b69bd1a0a7a99f2c0d80933ad2eea44c8c71b2))
* **installation:** first PowerShell command ([aa9a943d](https://github.com/rust-lang/rustlings/commit/aa9a943ddf3ae260782e73c26bcc9db60e5894b6))
* **iterators5:** derive Clone, Copy ([91fc9e31](https://github.com/rust-lang/rustlings/commit/91fc9e3118f4af603c9911698cc2a234725cb032))
* **quiz1:** Updated question description (#794) ([d8766496](https://github.com/rust-lang/rustlings/commit/d876649616cc8a8dd5f539f8bc1a5434b960b1e9))
* **try_from_into, from_str:** hints for dyn Error ([11d2cf0d](https://github.com/rust-lang/rustlings/commit/11d2cf0d604dee3f5023c17802d69438e69fa50e))
* **variables5:** confine the answer further ([48ffcbd2](https://github.com/rust-lang/rustlings/commit/48ffcbd2c4cc4d936c2c7480019190f179813cc5))
<a name="4.4.0"></a>
## 4.4.0 (2021-04-24)
#### Bug Fixes
* Fix spelling error in main.rs ([91ee27f2](https://github.com/rust-lang/rustlings/commit/91ee27f22bd3797a9db57e5fd430801c170c5db8))
* typo in default out text ([644c49f1](https://github.com/rust-lang/rustlings/commit/644c49f1e04cbb24e95872b3a52b07d692ae3bc8))
* **collections:** Naming exercises for vectors and hashmap ([bef39b12](https://github.com/rust-lang/rustlings/commit/bef39b125961310b34b34871e480a82e82af4678))
* **from_str:**
* Correct typos ([5f7c89f8](https://github.com/rust-lang/rustlings/commit/5f7c89f85db1f33da01911eaa479c3a2d4721678))
* test for error instead of unwrap/should_panic ([15e71535](https://github.com/rust-lang/rustlings/commit/15e71535f37cfaed36e22eb778728d186e2104ab))
* use trait objects for from_str ([c3e7b831](https://github.com/rust-lang/rustlings/commit/c3e7b831786c9172ed8bd5d150f3c432f242fba9))
* **functions3:** improve function argument type (#687) ([a6509cc4](https://github.com/rust-lang/rustlings/commit/a6509cc4d545d8825f01ddf7ee37823b372154dd))
* **hashmap2:** Update incorrect assertion (#660) ([72aaa15e](https://github.com/rust-lang/rustlings/commit/72aaa15e6ab4b72b3422f1c6356396e20a2a2bb8))
* **info:** Fix typo (#635) ([cddc1e86](https://github.com/rust-lang/rustlings/commit/cddc1e86e7ec744ee644cc774a4887b1a0ded3e8))
* **iterators2:** Moved errors out of tests. ([baf4ba17](https://github.com/rust-lang/rustlings/commit/baf4ba175ba6eb92989e3dd54ecbec4bedc9a863), closes [#359](https://github.com/rust-lang/rustlings/issues/359))
* **iterators3:** Enabled iterators3.rs to run without commented out tests. ([c6712dfc](https://github.com/rust-lang/rustlings/commit/c6712dfccd1a093e590ad22bbc4f49edc417dac0))
* **main:** Let find_exercise work with borrows ([347f30bd](https://github.com/rust-lang/rustlings/commit/347f30bd867343c5ace1097e085a1f7e356553f7))
* **move_semantics4:**
* Remove redundant "instead" (#640) ([cc266d7d](https://github.com/rust-lang/rustlings/commit/cc266d7d80b91e79df3f61984f231b7f1587218e))
* Small readbility improvement (#617) ([10965920](https://github.com/rust-lang/rustlings/commit/10965920fbdf8a1efc85bed869e55a1787006404))
* **option2:** Rename uninformative variables (#675) ([b4de6594](https://github.com/rust-lang/rustlings/commit/b4de6594380636817d13c2677ec6f472a964cf43))
* **quiz3:** Force an answer to Q2 (#672) ([0d894e6f](https://github.com/rust-lang/rustlings/commit/0d894e6ff739943901e1ae8c904582e5c2f843bd))
* **structs:** Add 5.3 to structs/README (#652) ([6bd791f2](https://github.com/rust-lang/rustlings/commit/6bd791f2f44aa7f0ad926df767f6b1fa8f12a9a9))
* **structs2:** correct grammar in hint (#663) ([ebdb66c7](https://github.com/rust-lang/rustlings/commit/ebdb66c7bfb6d687a14cc511a559a222e6fc5de4))
* **structs3:**
* reword heading comment (#664) ([9f3e8c2d](https://github.com/rust-lang/rustlings/commit/9f3e8c2dde645e5264c2d2200e68842b5f47bfa3))
* add check to prevent naive implementation of is_international ([05a753fe](https://github.com/rust-lang/rustlings/commit/05a753fe6333d36dbee5f68c21dec04eacdc75df))
* **threads1:** line number correction ([7857b0a6](https://github.com/rust-lang/rustlings/commit/7857b0a689b0847f48d8c14cbd1865e3b812d5ca))
* **try_from_into:** use trait objects ([2e93a588](https://github.com/rust-lang/rustlings/commit/2e93a588e0abe8badb7eafafb9e7d073c2be5df8))
#### Features
* Replace clap with argh ([7928122f](https://github.com/rust-lang/rustlings/commit/7928122fcef9ca7834d988b1ec8ca0687478beeb))
* Replace emojis when NO_EMOJI env variable present ([8d62a996](https://github.com/rust-lang/rustlings/commit/8d62a9963708dbecd9312e8bcc4b47049c72d155))
* Added iterators5.rs exercise. ([b29ea17e](https://github.com/rust-lang/rustlings/commit/b29ea17ea94d1862114af2cf5ced0e09c197dc35))
* **arc1:** Add more details to description and hint (#710) ([81be4044](https://github.com/rust-lang/rustlings/commit/81be40448777fa338ebced3b0bfc1b32d6370313))
* **cli:** Improve the list command with options, and then some ([8bbe4ff1](https://github.com/rust-lang/rustlings/commit/8bbe4ff1385c5c169c90cd3ff9253f9a91daaf8e))
* **list:**
* updated progress percentage ([1c6f7e4b](https://github.com/rust-lang/rustlings/commit/1c6f7e4b7b9b3bd36f4da2bb2b69c549cc8bd913))
* added progress info ([c0e3daac](https://github.com/rust-lang/rustlings/commit/c0e3daacaf6850811df5bc57fa43e0f249d5cfa4))
<a name="4.3.0"></a>
## 4.3.0 (2020-12-29)
#### Features
* Rewrite default out text ([44d39112](https://github.com/rust-lang/rustlings/commit/44d39112ff122b29c9793fe52e605df1612c6490))
* match exercise order to book chapters (#541) ([033bf119](https://github.com/rust-lang/rustlings/commit/033bf1198fc8bfce1b570e49da7cde010aa552e3))
* Crab? (#586) ([fa9f522b](https://github.com/rust-lang/rustlings/commit/fa9f522b7f043d7ef73a39f003a9272dfe72c4f4))
* add "rustlings list" command ([838f9f30](https://github.com/rust-lang/rustlings/commit/838f9f30083d0b23fd67503dcf0fbeca498e6647))
* **try_from_into:** remove duplicate annotation ([04f1d079](https://github.com/rust-lang/rustlings/commit/04f1d079aa42a2f49af694bc92c67d731d31a53f))
#### Bug Fixes
* update structs README ([bcf14cf6](https://github.com/rust-lang/rustlings/commit/bcf14cf677adb3a38a3ac3ca53f3c69f61153025))
* added missing exercises to info.toml ([90cfb6ff](https://github.com/rust-lang/rustlings/commit/90cfb6ff28377531bfc34acb70547bdb13374f6b))
* gives a bit more context to magic number ([30644c9a](https://github.com/rust-lang/rustlings/commit/30644c9a062b825c0ea89435dc59f0cad86b110e))
* **functions2:** Change signature to trigger precise error message: (#605) ([0ef95947](https://github.com/rust-lang/rustlings/commit/0ef95947cc30482e63a7045be6cc2fb6f6dcb4cc))
* **structs1:** Adjust wording (#573) ([9334783d](https://github.com/rust-lang/rustlings/commit/9334783da31d821cc59174fbe8320df95828926c))
* **try_from_into:**
* type error ([4f4cfcf3](https://github.com/rust-lang/rustlings/commit/4f4cfcf3c36c8718c7c170c9c3a6935e6ef0618c))
* Update description (#584) ([96347df9](https://github.com/rust-lang/rustlings/commit/96347df9df294f01153b29d9ad4ba361f665c755))
* **vec1:** Have test compare every element in a and v ([9b6c6293](https://github.com/rust-lang/rustlings/commit/9b6c629397b24b944f484f5b2bbd8144266b5695))
<a name="4.2.0"></a>
## 4.2.0 (2020-11-07)
#### Features
* Add HashMap exercises ([633c00cf](https://github.com/rust-lang/rustlings/commit/633c00cf8071e1e82959a3010452a32f34f29fc9))
* Add Vec exercises ([0c12fa31](https://github.com/rust-lang/rustlings/commit/0c12fa31c57c03c6287458a0a8aca7afd057baf6))
* **primitive_types6:** Add a test (#548) ([2b1fb2b7](https://github.com/rust-lang/rustlings/commit/2b1fb2b739bf9ad8d6b7b12af25fee173011bfc4))
* **try_from_into:** Add tests (#571) ([95ccd926](https://github.com/rust-lang/rustlings/commit/95ccd92616ae79ba287cce221101e0bbe4f68cdc))
#### Bug Fixes
* log error output when inotify limit is exceeded ([d61b4e5a](https://github.com/rust-lang/rustlings/commit/d61b4e5a13b44d72d004082f523fa1b6b24c1aca))
* more unique temp_file ([5643ef05](https://github.com/rust-lang/rustlings/commit/5643ef05bc81e4a840e9456f4406a769abbe1392))
* **installation:** Update the MinRustVersion ([21bfb2d4](https://github.com/rust-lang/rustlings/commit/21bfb2d4777429c87d8d3b5fbf0ce66006dcd034))
* **iterators2:** Update description (#578) ([197d3a3d](https://github.com/rust-lang/rustlings/commit/197d3a3d8961b2465579218a6749b2b2cefa8ddd))
* **primitive_types6:**
* remove 'unused doc comment' warning ([472d8592](https://github.com/rust-lang/rustlings/commit/472d8592d65c8275332a20dfc269e7ac0d41bc88))
* missing comma in test ([4fb230da](https://github.com/rust-lang/rustlings/commit/4fb230daf1251444fcf29e085cee222a91f8a37e))
* **quiz3:** Second test is for odd numbers, not even. (#553) ([18e0bfef](https://github.com/rust-lang/rustlings/commit/18e0bfef1de53071e353ba1ec5837002ff7290e6))
<a name="4.1.0"></a>
## 4.1.0 (2020-10-05)
#### Bug Fixes
* Update rustlings version in Cargo.lock ([1cc40bc9](https://github.com/rust-lang/rustlings/commit/1cc40bc9ce95c23d56f6d91fa1c4deb646231fef))
* **arc1:** index mod should equal thread count ([b4062ef6](https://github.com/rust-lang/rustlings/commit/b4062ef6993e80dac107c4093ea85166ad3ee0fa))
* **enums3:** Update Message::ChangeColor to take a tuple. (#457) ([4b6540c7](https://github.com/rust-lang/rustlings/commit/4b6540c71adabad647de8a09e57295e7c7c7d794))
* **exercises:** adding question mark to quiz2 ([101072ab](https://github.com/rust-lang/rustlings/commit/101072ab9f8c80b40b8b88cb06cbe38aca2481c5))
* **generics3:** clarify grade change ([47f7672c](https://github.com/rust-lang/rustlings/commit/47f7672c0307732056e7426e81d351f0dd7e22e5))
* **structs3:** Small adjustment of variable name ([114b54cb](https://github.com/rust-lang/rustlings/commit/114b54cbdb977234b39e5f180d937c14c78bb8b2))
* **using_as:** Add test so that proper type is returned. (#512) ([3286c5ec](https://github.com/rust-lang/rustlings/commit/3286c5ec19ea5fb7ded81d047da5f8594108a490))
#### Features
* Added iterators1.rs exercise ([9642f5a3](https://github.com/rust-lang/rustlings/commit/9642f5a3f686270a4f8f6ba969919ddbbc4f7fdd))
* Add ability to run rustlings on repl.it (#471) ([8f7b5bd0](https://github.com/rust-lang/rustlings/commit/8f7b5bd00eb83542b959830ef55192d2d76db90a))
* Add gitpod support (#473) ([4821a8be](https://github.com/rust-lang/rustlings/commit/4821a8be94af4f669042a06ab917934cfacd032f))
* Remind the user of the hint option (#425) ([816b1f5e](https://github.com/rust-lang/rustlings/commit/816b1f5e85d6cc6e72673813a85d0ada2a8f84af))
* Remind the user of the hint option (#425) ([9f61db5d](https://github.com/rust-lang/rustlings/commit/9f61db5dbe38538cf06571fcdd5f806e7901e83a))
* **cli:** Added 'cls' command to 'watch' mode (#474) ([4f2468e1](https://github.com/rust-lang/rustlings/commit/4f2468e14f574a93a2e9b688367b5752ed96ae7b))
* **try_from_into:** Add insufficient length test (#469) ([523d18b8](https://github.com/rust-lang/rustlings/commit/523d18b873a319f7c09262f44bd40e2fab1830e5))
<a name="4.0.0"></a>
## 4.0.0 (2020-07-08)
#### Breaking Changes
* Add a --nocapture option to display test harnesses' outputs ([8ad5f9bf](https://github.com/rust-lang/rustlings/commit/8ad5f9bf531a4848b1104b7b389a20171624c82f))
* Rename test to quiz, fixes #244 ([010a0456](https://github.com/rust-lang/rustlings/commit/010a04569282149cea7f7a76fc4d7f4c9f0f08dd))
#### Features
* Add traits README ([173bb141](https://github.com/rust-lang/rustlings/commit/173bb14140c5530cbdb59e53ace3991a99d804af))
* Add box1.rs exercise ([7479a473](https://github.com/rust-lang/rustlings/commit/7479a4737bdcac347322ad0883ca528c8675e720))
* Rewrite try_from_into (#393) ([763aa6e3](https://github.com/rust-lang/rustlings/commit/763aa6e378a586caae2d8d63755a85eeba227933))
* Add if2 exercise ([1da84b5f](https://github.com/rust-lang/rustlings/commit/1da84b5f7c489f65bd683c244f13c7d1ee812df0))
* Added exercise structs3.rs ([b66e2e09](https://github.com/rust-lang/rustlings/commit/b66e2e09622243e086a0f1258dd27e1a2d61c891))
* Add exercise variables6 covering const (#352) ([5999acd2](https://github.com/rust-lang/rustlings/commit/5999acd24a4f203292be36e0fd18d385887ec481))
#### Bug Fixes
* Change then to than ([ddd98ad7](https://github.com/rust-lang/rustlings/commit/ddd98ad75d3668fbb10eff74374148aa5ed2344d))
* rename quiz1 to tests1 in info (#420) ([0dd1c6ca](https://github.com/rust-lang/rustlings/commit/0dd1c6ca6b389789e0972aa955fe17aa15c95f29))
* fix quiz naming inconsistency (#421) ([5563adbb](https://github.com/rust-lang/rustlings/commit/5563adbb890587fc48fbbc9c4028642687f1e85b))
* confine the user further in variable exercises ([06ef4cc6](https://github.com/rust-lang/rustlings/commit/06ef4cc654e75d22a526812919ee49b8956280bf))
* update iterator and macro text for typos and clarity ([95900828](https://github.com/rust-lang/rustlings/commit/959008284834bece0196a01e17ac69a7e3590116))
* update generics2 closes #362 ([964c974a](https://github.com/rust-lang/rustlings/commit/964c974a0274199d755073b917c2bc5da0c9b4f1))
* confusing comment in conversions/try_from_into.rs ([c9e4f2cf](https://github.com/rust-lang/rustlings/commit/c9e4f2cfb4c48d0b7451263cfb43b9426438122d))
* **arc1:** Passively introduce attributes (#429) ([113cdae2](https://github.com/rust-lang/rustlings/commit/113cdae2d4e4c55905e8056ad326ede7fd7de356))
* **box1:** fix comment typo (#426) ([bb2ca251](https://github.com/rust-lang/rustlings/commit/bb2ca251106b27a7272d9a30872904dd1376654c))
* **errorsn:** Try harder to confine the user. (#388) ([2b20c8a0](https://github.com/rust-lang/rustlings/commit/2b20c8a0f5774d07c58d110d75879f33fc6273b5))
* **from_into.rs:** typo ([a901499e](https://github.com/rust-lang/rustlings/commit/a901499ededd3ce1995164700514fe4e9a0373ea))
* **generics2:** Guide students to the answer (#430) ([e6bd8021](https://github.com/rust-lang/rustlings/commit/e6bd8021d9a7dd06feebc30c9d5f953901d7b419))
* **installation:**
* Provide a backup git reference when tag can't be curl ([9e4fb100](https://github.com/rust-lang/rustlings/commit/9e4fb1009f1c9e3433915c03e22c2af422e5c5fe))
* Check if python is available while checking for git,rustc and cargo ([9cfb617d](https://github.com/rust-lang/rustlings/commit/9cfb617d5b0451b4b51644a1298965390cda9884))
* **option1:**
* Don't add only zeros to the numbers array ([cce6a442](https://github.com/rust-lang/rustlings/commit/cce6a4427718724a9096800754cd3abeca6a1580))
* Add cast to usize, as it is confusing in the context of an exercise about Option ([f6cffc7e](https://github.com/rust-lang/rustlings/commit/f6cffc7e487b42f15a6f958e49704c93a8d4465b))
* **option2:** Add TODO to comments (#400) ([10967bce](https://github.com/rust-lang/rustlings/commit/10967bce57682812dc0891a9f9757da1a9d87404))
* **options1:** Add hint about Array Initialization (#389) ([9f75554f](https://github.com/rust-lang/rustlings/commit/9f75554f2a30295996f03f0160b98c0458305502))
* **test2:** name of type String and &str (#394) ([d6c0a688](https://github.com/rust-lang/rustlings/commit/d6c0a688e6a96f93ad60d540d4b326f342fc0d45))
* **variables6:** minor typo (#419) ([524e17df](https://github.com/rust-lang/rustlings/commit/524e17df10db95f7b90a0f75cc8997182a8a4094))
<a name="3.0.0"></a>
## 3.0.0 (2020-04-11)
#### Breaking Changes
* make "compile" exercises print output (#278) ([3b6d5c](https://github.com/fmoko/rustlings/commit/3b6d5c3aaa27a242a832799eb66e96897d26fde3))
#### Bug Fixes
* **primitive_types:** revert primitive_types4 (#296) ([b3a3351e](https://github.com/rust-lang/rustlings/commit/b3a3351e8e6a0bdee07077d7b0382953821649ae))
* **run:** compile clippy exercise files (#295) ([3ab084a4](https://github.com/rust-lang/rustlings/commit/3ab084a421c0f140ae83bf1fc3f47b39342e7373))
* **conversions:**
* add additional test to meet exercise rules (#284) ([bc22ec3](https://github.com/fmoko/rustlings/commit/bc22ec382f843347333ef1301fc1bad773657f38))
* remove duplicate not done comment (#292) ([dab90f](https://github.com/fmoko/rustlings/commit/dab90f7b91a6000fe874e3d664f244048e5fa342))
* don't hardcode documentation version for traits (#288) ([30e6af](https://github.com/fmoko/rustlings/commit/30e6af60690c326fb5d3a9b7335f35c69c09137d))
#### Features
* add Option2 exercise (#290) ([86b5c08b](https://github.com/rust-lang/rustlings/commit/86b5c08b9bea1576127a7c5f599f5752072c087d))
* add exercise for option (#282) ([135e5d47](https://github.com/rust-lang/rustlings/commit/135e5d47a7c395aece6f6022117fb20c82f2d3d4))
* add new exercises for generics (#280) ([76be5e4e](https://github.com/rust-lang/rustlings/commit/76be5e4e991160f5fd9093f03ee2ba260e8f7229))
* **ci:** add buildkite config ([b049fa2c](https://github.com/rust-lang/rustlings/commit/b049fa2c84dba0f0c8906ac44e28fd45fba51a71))
<a name="2.2.1"></a>
### 2.2.1 (2020-02-27)
#### Bug Fixes
* Re-add cloning the repo to install scripts ([3d9b03c5](https://github.com/rust-lang/rustlings/commit/3d9b03c52b8dc51b140757f6fd25ad87b5782ef5))
#### Features
* Add clippy lints (#269) ([1e2fd9c9](https://github.com/rust-lang/rustlings/commit/1e2fd9c92f8cd6e389525ca1a999fca4c90b5921))
<a name="2.2.0"></a>
## 2.2.0 (2020-02-25)
#### Bug Fixes
* Update deps to version compatable with aarch64-pc-windows (#263) ([19a93428](https://github.com/rust-lang/rustlings/commit/19a93428b3c73d994292671f829bdc8e5b7b3401))
* **docs:**
* Added a necessary step to Windows installation process (#242) ([3906efcd](https://github.com/rust-lang/rustlings/commit/3906efcd52a004047b460ed548037093de3f523f))
* Fixed mangled sentence from book; edited for clarity (#266) ([ade52ff](https://github.com/rust-lang/rustlings/commit/ade52ffb739987287ddd5705944c8777705faed9))
* Updated iterators readme to account for iterators4 exercise (#273) ([bec8e3a](https://github.com/rust-lang/rustlings/commit/bec8e3a644cbd88db1c73ea5f1d8a364f4a34016))
* **installation:** make fatal errors more obvious (#272) ([17d0951e](https://github.com/rust-lang/rustlings/commit/17d0951e66fda8e11b204d5c4c41a0d5e22e78f7))
* **iterators2:**
* Remove reference to missing iterators2.rs (#245) ([419f7797](https://github.com/rust-lang/rustlings/commit/419f7797f294e4ce6a2b883199731b5bde77d262))
* **as_ref_mut:** Enable a test and improve per clippy's suggestion (#256) ([dfdf809](https://github.com/rust-lang/rustlings/commit/dfdf8093ebbd4145864995627b812780de52f902))
* **tests1:**
* Change test command ([fe10e06c](https://github.com/rust-lang/rustlings/commit/fe10e06c3733ddb4a21e90d09bf79bfe618e97ce)
* Correct test command in tests1.rs comment (#263) ([39fa7ae](https://github.com/rust-lang/rustlings/commit/39fa7ae8b70ad468da49b06f11b2383135a63bcf))
#### Features
* Add variables5.rs exercise (#264) ([0c73609e](https://github.com/rust-lang/rustlings/commit/0c73609e6f2311295e95d6f96f8c747cfc4cba03))
* Show a completion message when watching (#253) ([d25ee55a](https://github.com/rust-lang/rustlings/commit/d25ee55a3205882d35782e370af855051b39c58c))
* Add type conversion and parsing exercises (#249) ([0c85dc11](https://github.com/rust-lang/rustlings/commit/0c85dc1193978b5165491b99cc4922caf8d14a65))
* Created consistent money unit (#258) ([fd57f8f](https://github.com/rust-lang/rustlings/commit/fd57f8f2c1da2af8ddbebbccec214e6f40f4dbab))
* Enable test for exercise test4 (#276) ([8b971ff](https://github.com/rust-lang/rustlings/commit/8b971ffab6079a706ac925f5917f987932b55c07))
* Added traits exercises (#274 but specifically #216, which originally added
this :heart:) ([b559cdd](https://github.com/rust-lang/rustlings/commit/b559cdd73f32c0d0cfc1feda39f82b3e3583df17))
<a name="2.1.0"></a>
## 2.1.0 (2019-11-27)
#### Bug Fixes
* add line numbers in several exercises and hints ([b565c4d3](https://github.com/rust-lang/rustlings/commit/b565c4d3e74e8e110bef201a082fa1302722a7c3))
* **arc1:** Fix some words in the comment ([c42c3b21](https://github.com/rust-lang/rustlings/commit/c42c3b2101df9164c8cd7bb344def921e5ba3e61))
* **enums:** Add link to chapter on pattern syntax (#242) ([615ce327](https://github.com/rust-lang/rustlings/commit/615ce3279800c56d89f19d218ccb7ef576624feb))
* **primitive_types4:**
* update outdated hint ([4c5189df](https://github.com/rust-lang/rustlings/commit/4c5189df2bdd9a231f6b2611919ba5aa14da0d3f))
* update outdated comment ([ded2c034](https://github.com/rust-lang/rustlings/commit/ded2c034ba93fa1e3c2c2ea16b83abc1a57265e8))
* **strings2:** update line number in hint ([a09f684f](https://github.com/rust-lang/rustlings/commit/a09f684f05c58d239a6fc59ec5f81c2533e8b820))
* **variables1:** Correct wrong word in comment ([fda5a470](https://github.com/rust-lang/rustlings/commit/fda5a47069e0954f16a04e8e50945e03becb71a5))
#### Features
* **watch:** show hint while watching ([8143d57b](https://github.com/rust-lang/rustlings/commit/8143d57b4e88c51341dd4a18a14c536042cc009c))
<a name="2.0.0"></a>
## 2.0.0 (2019-11-12)
#### Bug Fixes
* **default:** Clarify the installation procedure ([c371b853](https://github.com/rust-lang/rustlings/commit/c371b853afa08947ddeebec0edd074b171eeaae0))
* **info:** Fix trailing newlines for hints ([795b6e34](https://github.com/rust-lang/rustlings/commit/795b6e348094a898e9227a14f6232f7bb94c8d31))
* **run:** make `run` never prompt ([4b265465](https://github.com/rust-lang/rustlings/commit/4b26546589f7d2b50455429482cf1f386ceae8b3))
#### Breaking Changes
* Refactor hint system ([9bdb0a12](https://github.com/rust-lang/rustlings/commit/9bdb0a12e45a8e9f9f6a4bd4a9c172c5376c7f60))
* improve `watch` execution mode ([2cdd6129](https://github.com/rust-lang/rustlings/commit/2cdd61294f0d9a53775ee24ad76435bec8a21e60))
* Index exercises by name ([627cdc07](https://github.com/rust-lang/rustlings/commit/627cdc07d07dfe6a740e885e0ddf6900e7ec336b))
* **run:** makes `run` never prompt ([4b265465](https://github.com/rust-lang/rustlings/commit/4b26546589f7d2b50455429482cf1f386ceae8b3))
#### Features
* **cli:** check for rustc before doing anything ([36a033b8](https://github.com/rust-lang/rustlings/commit/36a033b87a6549c1e5639c908bf7381c84f4f425))
* **hint:** Add test for hint ([ce9fa6eb](https://github.com/rust-lang/rustlings/commit/ce9fa6ebbfdc3e7585d488d9409797285708316f))
<a name="1.5.1"></a>
### 1.5.1 (2019-11-11)
#### Bug Fixes
* **errors3:** Update hint ([dcfb427b](https://github.com/rust-lang/rustlings/commit/dcfb427b09585f0193f0a294443fdf99f11c64cb), closes [#185](https://github.com/rust-lang/rustlings/issues/185))
* **if1:** Remove `return` reference ([ad03d180](https://github.com/rust-lang/rustlings/commit/ad03d180c9311c0093e56a3531eec1a9a70cdb45))
* **strings:** Move Strings before Structs ([6dcecb38](https://github.com/rust-lang/rustlings/commit/6dcecb38a4435593beb87c8e12d6314143631482), closes [#204](https://github.com/rust-lang/rustlings/issues/204))
* **structs1:** Remove misleading comment ([f72e5a8f](https://github.com/rust-lang/rustlings/commit/f72e5a8f05568dde04eaeac10b9a69872f21cb37))
* **threads:** Move Threads behind SLT ([fbe91a67](https://github.com/rust-lang/rustlings/commit/fbe91a67a482bfe64cbcdd58d06ba830a0f39da3), closes [#205](https://github.com/rust-lang/rustlings/issues/205))
* **watch:** clear screen before each `verify()` ([3aff590](https://github.com/rust-lang/rustlings/commit/3aff59085586c24196a547c2693adbdcf4432648))
<a name="1.5.0"></a>
## 1.5.0 (2019-11-09)
#### Bug Fixes
* **test1:** Rewrite logic ([79a56942](https://github.com/rust-lang/rustlings/commit/79a569422c8309cfc9e4aed25bf4ab3b3859996b))
* **installation:** Fix rustlings installation check ([7a252c47](https://github.com/rust-lang/rustlings/commit/7a252c475551486efb52f949b8af55803b700bc6))
* **iterators:** Rename iterator3.rs ([433d2115](https://github.com/rust-lang/rustlings/commit/433d2115bc1c04b6d34a335a18c9a8f3e2672bc6))
* **iterators2:** Remove syntax resulting in misleading error message ([4cde8664](https://github.com/rust-lang/rustlings/commit/4cde86643e12db162a66e62f23b78962986046ac))
* **option1:**
* Fix arguments passed to assert! macro (#222) ([4c2cf6da](https://github.com/rust-lang/rustlings/commit/4c2cf6da755efe02725e05ecc3a303304c10a6da))
* Fix arguments passed to assert! macro ([ead4f7af](https://github.com/rust-lang/rustlings/commit/ead4f7af9e10e53418efdde5c359159347282afd))
* Add test for prematurely passing exercise ([a750e4a1](https://github.com/rust-lang/rustlings/commit/a750e4a1a3006227292bb17d57d78ce84da6bfc6))
* **primitive_types4:** Fail on a slice covering the wrong area ([5b1e673c](https://github.com/rust-lang/rustlings/commit/5b1e673cec1658afc4ebbbc800213847804facf5))
* **readme:** http to https ([70946b85](https://github.com/rust-lang/rustlings/commit/70946b85e536e80e70ed9505cb650ca0a3a1fbb5))
* **test1:**
* Swap assertion parameter order ([4086d463](https://github.com/rust-lang/rustlings/commit/4086d463a981e81d97781851d17db2ced290f446))
* renamed function name to snake case closes #180 ([89d5186c](https://github.com/rust-lang/rustlings/commit/89d5186c0dae8135ecabf90ee8bb35949bc2d29b))
#### Features
* Add enums exercises ([dc150321](https://github.com/rust-lang/rustlings/commit/dc15032112fc485226a573a18139e5ce928b1755))
* Added exercise for struct update syntax ([1c4c8764](https://github.com/rust-lang/rustlings/commit/1c4c8764ed118740cd4cee73272ddc6cceb9d959))
* **iterators2:** adds iterators2 exercise including config ([9288fccf](https://github.com/rust-lang/rustlings/commit/9288fccf07a2c5043b76d0fd6491e4cf72d76031))
<a name="1.4.1"></a>
### 1.4.1 (2019-08-13)
#### Bug Fixes
* **iterators2:** Remove syntax resulting in misleading error message ([4cde8664](https://github.com/rust-lang/rustlings/commit/4cde86643e12db162a66e62f23b78962986046ac))
* **option1:** Add test for prematurely passing exercise ([a750e4a1](https://github.com/rust-lang/rustlings/commit/a750e4a1a3006227292bb17d57d78ce84da6bfc6))
* **test1:** Swap assertion parameter order ([4086d463](https://github.com/rust-lang/rustlings/commit/4086d463a981e81d97781851d17db2ced290f446))
<a name="1.4.0"></a>
## 1.4.0 (2019-07-13)
#### Bug Fixes
* **installation:** Fix rustlings installation check ([7a252c47](https://github.com/rust-lang/rustlings/commit/7a252c475551486efb52f949b8af55803b700bc6))
* **iterators:** Rename iterator3.rs ([433d2115](https://github.com/rust-lang/rustlings/commit/433d2115bc1c04b6d34a335a18c9a8f3e2672bc6))
* **readme:** http to https ([70946b85](https://github.com/rust-lang/rustlings/commit/70946b85e536e80e70ed9505cb650ca0a3a1fbb5))
* **test1:** renamed function name to snake case ([89d5186c](https://github.com/rust-lang/rustlings/commit/89d5186c0dae8135ecabf90ee8bb35949bc2d29b))
* **cli:** Check if changed exercise file exists before calling verify ([ba85ca3](https://github.com/rust-lang/rustlings/commit/ba85ca32c4cfc61de46851ab89f9c58a28f33c88))
* **structs1:** Fix the irrefutable let pattern warning ([cc6a141](https://github.com/rust-lang/rustlings/commit/cc6a14104d7c034eadc98297eaaa972d09c50b1f))
#### Features
* **changelog:** Use clog for changelogs ([34e31232](https://github.com/rust-lang/rustlings/commit/34e31232dfddde284a341c9609b33cd27d9d5724))
* **iterators2:** adds iterators2 exercise including config ([9288fccf](https://github.com/rust-lang/rustlings/commit/9288fccf07a2c5043b76d0fd6491e4cf72d76031))
<a name="1.3.0"></a>
### 1.3.0 (2019-06-05)
#### Features
- Adds a simple exercise for structures (#163, @briankung)
#### Bug Fixes
- Add Result type signature as it is difficult for new comers to understand Generics and Error all at once. (#157, @veggiemonk)
- Rustfmt and whitespace fixes (#161, @eddyp)
- errorsn.rs: Separate also the hints from each other to avoid accidental viewing (#162, @eddyp)
- fixed outdated links (#165, @gushroom)
- Fix broken link (#164, @HanKruiger)
- Remove highlighting and syntect (#167, @komaeda)
<a name="1.2.2"></a>
### 1.2.2 (2019-05-07)
#### Bug Fixes
- Reverted `--nocapture` flag since it was causing tests to pass unconditionally
<a name="1.2.1"></a>
### 1.2.1 (2019-04-22)
#### Bug Fixes
- Fix the `--nocapture` feature (@komaeda)
- Provide a nicer error message for when you're in the wrong directory
<a name="1.2.0"></a>
### 1.2.0 (2019-04-22)
#### Features
- Add errors to exercises that compile without user changes (@yvan-sraka)
- Use --nocapture when testing, enabling `println!` when running (@komaeda)
<a name="1.1.1"></a>
### 1.1.1 (2019-04-14)
#### Bug fixes
- Fix permissions on exercise files (@zacanger, #133)
- Make installation checks more thorough (@komaeda, 1b3469f236bc6979c27f6e1a04e4138a88e55de3)
- Fix order of true/false in tests for executables (@mgeier, #137)
- Stop run from panicking when compile fails (@cjpearce, #141)
- Fix intermittent test failure caused by race condition (@cjpearce, #140)
- Fix links by deleting book version (@diodfr, #142)
- Canonicalize paths to fix path matching (@cjpearce, #143)
<a name="1.1.0"></a>
### 1.1.0 (2019-03-20)
- errors2.rs: update link to Rust book (#124)
- Start verification at most recently modified file (#120)
- Watch for file creation events in watch mode (#117)
- Add standard library types to exercises suite (#119)
- Give a warning when Rustlings isn't run from the right directory (#123)
- Verify that rust version is recent enough to install Rustlings (#131)
<a name="1.0.1"></a>
### 1.0.1 (2019-03-06)
- Adds a way to install Rustlings in one command (`curl -L https://git.io/rustlings | bash`)
- Makes `rustlings watch` react to create file events (@shaunbennett, #117)
- Reworks the exercise management to use an external TOML file instead of just listing them in the code
<a name="1.0.0"></a>
### 1.0.0 (2019-03-06)
Initial release.
================================================
FILE: assets/rustlings-zh/CONTRIBUTING.md
================================================
## Contributing to Rustlings
First off, thanks for taking the time to contribute!! ❤️
### Quick Reference
I want to...
_add an exercise! ➡️ [read this](#addex) and then [open a Pull Request](#prs)_
_update an outdated exercise! ➡️ [open a Pull Request](#prs)_
_report a bug! ➡️ [open an Issue](#issues)_
_fix a bug! ➡️ [open a Pull Request](#prs)_
_implement a new feature! ➡️ [open an Issue to discuss it first, then a Pull Request](#issues)_
<a name="#src"></a>
### Working on the source code
`rustlings` is basically a glorified `rustc` wrapper. Therefore the source code
isn't really that complicated since the bulk of the work is done by `rustc`.
`src/main.rs` contains a simple `clap` CLI that loads from `src/verify.rs` and `src/run.rs`.
<a name="addex"></a>
### Adding an exercise
The first step is to add the exercise! Name the file `exercises/yourTopic/yourTopicN.rs`, make sure to
put in some helpful links, and link to sections of the book in `exercises/yourTopic/README.md`.
Next make sure it runs with `rustlings`. The exercise metadata is stored in `info.toml`, under the `exercises` array. The order of the `exercises` array determines the order the exercises are run by `rustlings verify`.
Add the metadata for your exercise in the correct order in the `exercises` array. If you are unsure of the correct ordering, add it at the bottom and ask in your pull request. The exercise metadata should contain the following:
```diff
...
+ [[exercises]]
+ name = "yourTopicN"
+ path = "exercises/yourTopic/yourTopicN.rs"
+ mode = "compile"
+ hint = """
+ Some kind of useful hint for your exercise."""
...
```
The `mode` attribute decides whether Rustlings will only compile your exercise, or compile and test it. If you have tests to verify in your exercise, choose `test`, otherwise `compile`.
That's all! Feel free to put up a pull request.
<a name="issues"></a>
### Issues
You can open an issue [here](https://github.com/rust-lang/rustlings/issues/new).
If you're reporting a bug, please include the output of the following commands:
- `rustc --version`
- `rustlings --version`
- `ls -la`
- Your OS name and version
<a name="prs"></a>
### Pull Requests
Opening a pull request is as easy as forking the repository and committing your
changes. There's a couple of things to watch out for:
#### Write correct commit messages
We follow the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0-beta.4/)
specification, because it makes it easier to generate changelogs automatically.
This means that you have to format your commit messages in a specific way. Say
you're working on adding a new exercise called `foobar1.rs`. You could write
the following commit message:
```
feat: Add foobar1.rs exercise
```
If you're just fixing a bug, please use the `fix` type:
```
fix(verify): Make sure verify doesn't self-destruct
```
The scope within the brackets is optional, but should be any of these:
- `installation` (for the installation script)
- `cli` (for general CLI changes)
- `verify` (for the verification source file)
- `watch` (for the watch functionality source)
- `run` (for the run functionality source)
- `EXERCISENAME` (if you're changing a specific exercise, or set of exercises,
substitute them here)
When the commit also happens to close an existing issue, link it in the message
body:
```
fix: Update foobar
closes #101029908
```
If you're doing simple changes, like updating a book link, use `chore`:
```
chore: Update exercise1.rs book link
```
If you're updating documentation, use `docs`:
```
docs: Add more information to Readme
```
If, and only if, you're absolutely sure you want to make a breaking change
(please discuss this beforehand!), add an exclamation mark to the type and
explain the breaking change in the message body:
```
fix!: Completely change verification
BREAKING CHANGE: This has to be done because lorem ipsum dolor
```
#### Pull Request Workflow
Once you open a Pull Request, it may be reviewed or labeled (or both) until
the maintainers accept your change. Then, [bors](https://github.com/bors) will
run the test suite with your changes and if it's successful, automatically
merge it in!
================================================
FILE: assets/rustlings-zh/Cargo.toml
================================================
[package]
name = "rustlings"
version = "4.6.0"
authors = []
edition = "2021"
[dependencies]
argh = "0.1.4"
indicatif = "0.10.3"
console = "0.7.7"
notify = "4.0.15"
toml = "0.4.10"
regex = "1.5.5"
serde = {version = "1.0.10", features = ["derive"]}
[[bin]]
name = "rustlings"
path = "src/main.rs"
[dev-dependencies]
assert_cmd = "0.11.0"
predicates = "1.0.1"
glob = "0.3.0"
================================================
FILE: assets/rustlings-zh/LICENSE
================================================
The MIT License (MIT)
Copyright (c) 2016 Carol (Nichols || Goulding)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: assets/rustlings-zh/README.md
================================================
# rustlings-zh 🦀❤️
本项目是 [rustlings](https://github.com/rust-lang/rustlings) 的中文翻译版。
## 开始使用
_注意: 如果你在使用 macOS,确保已经安装了 Xcode 以及相应的开发者工具 `xcode-select --install`._
同时,你也需要安装Rust,具体参见<<精通Rust编程>>一书或者访问https://rustup.rs。
### 手动安装
Clone该项目,然后运行`cargo install`.
```bash
git clone https://github.com/sunface/rust-course
cd rustlings-zh
cargo install --force --path .
```
如果有安装错误,请先升级rust工具链
```bash
rustup update
```
然后, 运行`rustlings`来启动.
## 使用方式
练习题是按照专题(topic)来排序的,具体可以在`/exercises/<topic>`下找到。
完成练习的方式其实挺简单的,大多数可以通过修改代码、通过编译的方式来完成。还有些练习需要让你编写代码来通过测试,总之目标是比较简单的:让它运行起来。
我们强烈建议你按照推荐的顺序来做练习题,在终端执行:
```bash
rustlings watch
```
该命令会在预先定义的顺序下,来呈现练习题,同时,在你修改了`exercises/`下的任何一处代码并保存后,都会触发一次重新编译运行,因此无需再手动去编译运行。当然你也可以通过以下命令来只运行一次:
```bash
rustlings verify
```
和watch做的事情基本一致,但是在运行后会自动退出。
如果想要指定运行一个练习题,可以运行:
```bash
rustlings run myExercise1
```
或者也可以运行下一个未完成的练习
```bash
rustlings run next
```
一旦你遇到解决不了的问题,可以运行下面的命令来获得帮助提示:
``` bash
rustlings hint myExercise1
```
你也可以直接对下一道未解决的问题获取帮助提示:
``` bash
rustlings hint next
```
想要查看目前的学习进度:
```bash
rustlings list
```
## Testing yourself
在每完成几个专题后,会有一个 quiz 测验,这个测验是对这些内容的综合测试,可以在`exercises/quizN.rs`下找到
## Uninstalling rustlings
从系统中移除 rustlings 需要两个步骤。首先,移除已经安装的练习题文件夹:
``` bash
rm -rf rustlings # 或者你的自定义文件夹
```
其次,因为 rustlings 是通过`cargo install`安装的,所以你可以通过`cargo uninstall rustlings`来移除 `rustlings` 这个可执行二进制文件:
``` bash
cargo uninstall rustlings
```
最后...没有最后了,恭喜你,已经卸载完成。
================================================
FILE: assets/rustlings-zh/default_out.txt
================================================
感谢安装 Rustlings!
你还没有任何使用经验?不用担心,Rustlings 正是为初学者量身定做!我们将教你大量
有关 Rust 的知识, 但在我们开始之前,以下有几个关于如何使用 Rustlings 的说明:
1. Rustlings 的核心在于你需要去解决一些练习。这些练习通常有些语法上的错误导致了
他们无法通过编译或测试。有些又是逻辑上的问题。无论是什么错误,你的目标就是去找
到它们然后解决!当练习编译通过,这意味着你成功解决了!并且 Rustlings 也已向你
发起了下一题的挑战。
2. 如果你以 watch 模式运行 Rustlings (推荐),它将自动从第一个练习开始。不要
为运行 Rustlings 时弹出的错误信息而感到困惑。因为你一运行 Rustlings 就会弹出
错误信息!这是练习的一部分,所以快用编辑器打开练习文件,然后像侦探一样工作!
3. 如果你在一个练习中被卡住了,可以通过键入 'hint'(在观察模式下),或运行
`rustex hint myexercise`来查看提示。
4. 如果你认为某个练习毫无意义,请随时在 Github 打开一个 issue
(https://github.com/rustcollege/rust-exercise/issues/new)。我们积极地关注着项目的
每个问题和每一件事。其他学习者也这样做的话,这样你们就可以互相帮助了
都明白了吗?牛🐂!可以运行 `rustex watch` 开始你的第一个练习。注意,确保打开你的编辑器!
================================================
FILE: assets/rustlings-zh/exercises/README.md
================================================
# Exercise to Book Chapter mapping
| Exercise | Book Chapter |
|------------------------|--------------|
| variables | §3.1 |
| functions | §3.3 |
| if | §3.5 |
| move_semantics | §4.1 |
| primitive_types | §4.3 |
| structs | §5.1 |
| enums | §6 |
| modules | §7 |
| collections | §8.1, §8.3 |
| strings | §8.2 |
| error_handling | §9 |
| generics | §10 |
| option | §10.1 |
| traits | §10.2 |
| tests | §11.1 |
| standard_library_types | §13.2 |
| threads | §16.1 |
| macros | §19.6 |
| clippy | n/a |
| conversions | n/a |
================================================
FILE: assets/rustlings-zh/exercises/advanced_errors/advanced_errs1.rs
================================================
// advanced_errs1.rs
// Remember back in errors6, we had multiple mapping functions so that we
// could translate lower-level errors into our custom error type using
// `map_err()`? What if we could use the `?` operator directly instead?
// Make this code compile! Execute `rustlings hint advanced_errs1` for
// hints :)
// I AM NOT DONE
use std::num::ParseIntError;
use std::str::FromStr;
// This is a custom error type that we will be using in the `FromStr`
// implementation.
#[derive(PartialEq, Debug)]
enum ParsePosNonzeroError {
Creation(CreationError),
ParseInt(ParseIntError),
}
impl From<CreationError> for ParsePosNonzeroError {
fn from(e: CreationError) -> Self {
// TODO: complete this implementation so that the `?` operator will
// work for `CreationError`
}
}
// TODO: implement another instance of the `From` trait here so that the
// `?` operator will work in the other place in the `FromStr`
// implementation below.
// Don't change anything below this line.
impl FromStr for PositiveNonzeroInteger {
type Err = ParsePosNonzeroError;
fn from_str(s: &str) -> Result<PositiveNonzeroInteger, Self::Err> {
let x: i64 = s.parse()?;
Ok(PositiveNonzeroInteger::new(x)?)
}
}
#[derive(PartialEq, Debug)]
struct PositiveNonzeroInteger(u64);
#[derive(PartialEq, Debug)]
enum CreationError {
Negative,
Zero,
}
impl PositiveNonzeroInteger {
fn new(value: i64) -> Result<PositiveNonzeroInteger, CreationError> {
match value {
x if x < 0 => Err(CreationError::Negative),
x if x == 0 => Err(CreationError::Zero),
x => Ok(PositiveNonzeroInteger(x as u64)),
}
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_parse_error() {
// We can't construct a ParseIntError, so we have to pattern match.
assert!(matches!(
PositiveNonzeroInteger::from_str("not a number"),
Err(ParsePosNonzeroError::ParseInt(_))
));
}
#[test]
fn test_negative() {
assert_eq!(
PositiveNonzeroInteger::from_str("-555"),
Err(ParsePosNonzeroError::Creation(CreationError::Negative))
);
}
#[test]
fn test_zero() {
assert_eq!(
PositiveNonzeroInteger::from_str("0"),
Err(ParsePosNonzeroError::Creation(CreationError::Zero))
);
}
#[test]
fn test_positive() {
let x = PositiveNonzeroInteger::new(42);
assert!(x.is_ok());
assert_eq!(PositiveNonzeroInteger::from_str("42"), Ok(x.unwrap()));
}
}
================================================
FILE: assets/rustlings-zh/exercises/advanced_errors/advanced_errs2.rs
================================================
// advanced_errs2.rs
// This exercise demonstrates a few traits that are useful for custom error
// types to implement, especially so that other code can consume the custom
// error type more usefully.
// Make this compile, and make the tests pass!
// Execute `rustlings hint advanced_errs2` for hints.
// Steps:
// 1. Implement a missing trait so that `main()` will compile.
// 2. Complete the partial implementation of `From` for
// `ParseClimateError`.
// 3. Handle the missing error cases in the `FromStr` implementation for
// `Climate`.
// 4. Complete the partial implementation of `Display` for
// `ParseClimateError`.
// I AM NOT DONE
use std::error::Error;
use std::fmt::{self, Display, Formatter};
use std::num::{ParseFloatError, ParseIntError};
use std::str::FromStr;
// This is the custom error type that we will be using for the parser for
// `Climate`.
#[derive(Debug, PartialEq)]
enum ParseClimateError {
Empty,
BadLen,
NoCity,
ParseInt(ParseIntError),
ParseFloat(ParseFloatError),
}
// This `From` implementation allows the `?` operator to work on
// `ParseIntError` values.
impl From<ParseIntError> for ParseClimateError {
fn from(e: ParseIntError) -> Self {
Self::ParseInt(e)
}
}
// This `From` implementation allows the `?` operator to work on
// `ParseFloatError` values.
impl From<ParseFloatError> for ParseClimateError {
fn from(e: ParseFloatError) -> Self {
// TODO: Complete this function
}
}
// TODO: Implement a missing trait so that `main()` below will compile. It
// is not necessary to implement any methods inside the missing trait.
// The `Display` trait allows for other code to obtain the error formatted
// as a user-visible string.
impl Display for ParseClimateError {
// TODO: Complete this function so that it produces the correct strings
// for each error variant.
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
// Imports the variants to make the following code more compact.
use ParseClimateError::*;
match self {
NoCity => write!(f, "no city name"),
ParseFloat(e) => write!(f, "error parsing temperature: {}", e),
}
}
}
#[derive(Debug, PartialEq)]
struct Climate {
city: String,
year: u32,
temp: f32,
}
// Parser for `Climate`.
// 1. Split the input string into 3 fields: city, year, temp.
// 2. Return an error if the string is empty or has the wrong number of
// fields.
// 3. Return an error if the city name is empty.
// 4. Parse the year as a `u32` and return an error if that fails.
// 5. Parse the temp as a `f32` and return an error if that fails.
// 6. Return an `Ok` value containing the completed `Climate` value.
impl FromStr for Climate {
type Err = ParseClimateError;
// TODO: Complete this function by making it handle the missing error
// cases.
fn from_str(s: &str) -> Result<Self, Self::Err> {
let v: Vec<_> = s.split(',').collect();
let (city, year, temp) = match &v[..] {
[city, year, temp] => (city.to_string(), year, temp),
_ => return Err(ParseClimateError::BadLen),
};
let year: u32 = year.parse()?;
let temp: f32 = temp.parse()?;
Ok(Climate { city, year, temp })
}
}
// Don't change anything below this line (other than to enable ignored
// tests).
fn main() -> Result<(), Box<dyn Error>> {
println!("{:?}", "Hong Kong,1999,25.7".parse::<Climate>()?);
println!("{:?}", "".parse::<Climate>()?);
Ok(())
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_empty() {
let res = "".parse::<Climate>();
assert_eq!(res, Err(ParseClimateError::Empty));
assert_eq!(res.unwrap_err().to_string(), "empty input");
}
#[test]
fn test_short() {
let res = "Boston,1991".parse::<Climate>();
assert_eq!(res, Err(ParseClimateError::BadLen));
assert_eq!(res.unwrap_err().to_string(), "incorrect number of fields");
}
#[test]
fn test_long() {
let res = "Paris,1920,17.2,extra".parse::<Climate>();
assert_eq!(res, Err(ParseClimateError::BadLen));
assert_eq!(res.unwrap_err().to_string(), "incorrect number of fields");
}
#[test]
fn test_no_city() {
let res = ",1997,20.5".parse::<Climate>();
assert_eq!(res, Err(ParseClimateError::NoCity));
assert_eq!(res.unwrap_err().to_string(), "no city name");
}
#[test]
fn test_parse_int_neg() {
let res = "Barcelona,-25,22.3".parse::<Climate>();
assert!(matches!(res, Err(ParseClimateError::ParseInt(_))));
let err = res.unwrap_err();
if let ParseClimateError::ParseInt(ref inner) = err {
assert_eq!(
err.to_string(),
format!("error parsing year: {}", inner.to_string())
);
} else {
unreachable!();
};
}
#[test]
fn test_parse_int_bad() {
let res = "Beijing,foo,15.0".parse::<Climate>();
assert!(matches!(res, Err(ParseClimateError::ParseInt(_))));
let err = res.unwrap_err();
if let ParseClimateError::ParseInt(ref inner) = err {
assert_eq!(
err.to_string(),
format!("error parsing year: {}", inner.to_string())
);
} else {
unreachable!();
};
}
#[test]
fn test_parse_float() {
let res = "Manila,2001,bar".parse::<Climate>();
assert!(matches!(res, Err(ParseClimateError::ParseFloat(_))));
let err = res.unwrap_err();
if let ParseClimateError::ParseFloat(ref inner) = err {
assert_eq!(
err.to_string(),
format!("error parsing temperature: {}", inner.to_string())
);
} else {
unreachable!();
};
}
#[test]
fn test_parse_good() {
let res = "Munich,2015,23.1".parse::<Climate>();
assert_eq!(
res,
Ok(Climate {
city: "Munich".to_string(),
year: 2015,
temp: 23.1,
})
);
}
#[test]
#[ignore]
fn test_downcast() {
let res = "São Paulo,-21,28.5".parse::<Climate>();
assert!(matches!(res, Err(ParseClimateError::ParseInt(_))));
let err = res.unwrap_err();
let inner: Option<&(dyn Error + 'static)> = err.source();
assert!(inner.is_some());
assert!(inner.unwrap().is::<ParseIntError>());
}
}
================================================
FILE: assets/rustlings-zh/exercises/clippy/README.md
================================================
# Clippy
The Clippy tool is a collection of lints to analyze your code so you can catch common mistakes and improve your Rust code.
If you used the installation script for Rustlings, Clippy should be already installed.
If not you can install it manually via `rustup component add clippy`.
## Further information
- [GitHub Repository](https://github.com/rust-lang/rust-clippy).
================================================
FILE: assets/rustlings-zh/exercises/clippy/clippy1.rs
================================================
// clippy1.rs
// The Clippy tool is a collection of lints to analyze your code
// so you can catch common mistakes and improve your Rust code.
//
// For these exercises the code will fail to compile when there are clippy warnings
// check clippy's suggestions from the output to solve the exercise.
// Execute `rustlings hint clippy1` for hints :)
// I AM NOT DONE
fn main() {
let x = 1.2331f64;
let y = 1.2332f64;
if y != x {
println!("Success!");
}
}
================================================
FILE: assets/rustlings-zh/exercises/clippy/clippy2.rs
================================================
// clippy2.rs
// Make me compile! Execute `rustlings hint clippy2` for hints :)
// I AM NOT DONE
fn main() {
let mut res = 42;
let option = Some(12);
for x in option {
res += x;
}
println!("{}", res);
}
================================================
FILE: assets/rustlings-zh/exercises/collections/README.md
================================================
# 集合(Collections)
Rust 的标准库包含了很多有用的数据结构,它们称作为集合。
大多其它的数据类型通常仅表示一个特定的值,但集合可以包含多个值。
内置的数组和元组类型指向的数据存储在堆上,这意味着存储的数据不必在编译时确定,
并可以根据程序的运行来增加或减少。
本次练习将带你熟悉 Rust 程序中两个特别常用的基本数据结构:
* *vector* 能够存储一段连续且数量不定的值。
* *散列表(hash map)* 能够将某个值与一个特定的键关联起来。
你可能也知道它们:[C++ 中的 *unordered map*](https://en.cppreference.com/w/cpp/container/unordered_map)、[Python 的 *dictionary*](https://docs.python.org/3/tutorial/datastructures.html#dictionaries) 或其它语言中的 *associative array(译:关联数组、map、映射)*。
## 更多信息
- [Storing Lists of Values with Vectors](https://doc.rust-lang.org/stable/book/ch08-01-vectors.html)
- [Storing Keys with Associated Values in Hash Maps](https://doc.rust-lang.org/book/ch08-03-hash-maps.html)
================================================
FILE: assets/rustlings-zh/exercises/collections/hashmap1.rs
================================================
// hashmap1.rs
// 用散列表定义一个水果篮。以键表示水果的名称,值来代表篮子里对应水果的个数。
// 要求必须在篮子里放至少三种水果(如苹果、香蕉、芒果),每种水果的总数也应不少于五个。
//
// 让我通过编译和测试!
//
// 如果需要提示,可以执行命令 `rustlings hint hashmap1`。
// I AM NOT DONE
use std::collections::HashMap;
fn fruit_basket() -> HashMap<String, u32> {
let mut basket = // TODO:在这声明个散列表
// 给你两个香蕉
basket.insert(String::from("banana"), 2);
// TODO:在这往篮子里添加更多的水果
basket
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn at_least_three_types_of_fruits() {
let basket = fruit_basket();
assert!(basket.len() >= 3);
}
#[test]
fn at_least_five_fruits() {
let basket = fruit_basket();
assert!(basket.values().sum::<u32>() >= 5);
}
}
================================================
FILE: assets/rustlings-zh/exercises/collections/hashmap2.rs
================================================
// hashmap2.rs
// 给你一个用散列表表示的水果篮,它的键表示水果的名称,值表示篮子里对应水果的个数。
// 现在需要往篮子添加至少 11 种水果。篮子里已有 - 苹果 (4),
// 芒果 (2) 和荔枝 (5) 三种水果,你不能再添加这些水果。
//
// 让我通过测试!
//
// 如果需要提示,可以执行命令 `rustlings hint hashmap2`。
// I AM NOT DONE
use std::collections::HashMap;
#[derive(Hash, PartialEq, Eq)]
enum Fruit {
Apple,
Banana,
Mango,
Lychee,
Pineapple,
}
fn fruit_basket(basket: &mut HashMap<Fruit, u32>) {
let fruit_kinds = vec![
Fruit::Apple,
Fruit::Banana,
Fruit::Mango,
Fruit::Lychee,
Fruit::Pineapple,
];
for fruit in fruit_kinds {
// TODO:如果篮子里没有某种水果,就把它放入篮子。
// 注意,你不能放入篮子中任何已有的水果。
}
}
#[cfg(test)]
mod tests {
use super::*;
fn get_fruit_basket() -> HashMap<Fruit, u32> {
let mut basket = HashMap::<Fruit, u32>::new();
basket.insert(Fruit::Apple, 4);
basket.insert(Fruit::Mango, 2);
basket.insert(Fruit::Lychee, 5);
basket
}
#[test]
fn test_given_fruits_are_not_modified() {
let mut basket = get_fruit_basket();
fruit_basket(&mut basket);
assert_eq!(*basket.get(&Fruit::Apple).unwrap(), 4);
assert_eq!(*basket.get(&Fruit::Mango).unwrap(), 2);
assert_eq!(*basket.get(&Fruit::Lychee).unwrap(), 5);
}
#[test]
fn at_least_five_types_of_fruits() {
let mut basket = get_fruit_basket();
fruit_basket(&mut basket);
let count_fruit_kinds = basket.len();
assert!(count_fruit_kinds >= 5);
}
#[test]
fn greater_than_eleven_fruits() {
let mut basket = get_fruit_basket();
fruit_basket(&mut basket);
let count = basket.values().sum::<u32>();
assert!(count > 11);
}
}
================================================
FILE: assets/rustlings-zh/exercises/collections/vec1.rs
================================================
// vec1.rs
// 你的任务是创建一个与数组 `a` 中的元素完全相同的 `Vec`。
// 让我通过编译和测试!
// 如果需要提示,可以执行命令 `rustlings hint vec1`。
// I AM NOT DONE
fn array_and_vec() -> ([i32; 4], Vec<i32>) {
let a = [10, 20, 30, 40]; // 一个普通的数组
let v = // TODO:在这里用 vectors 的宏来声明你的 vector
(a, v)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_array_and_vec_similarity() {
let (a, v) = array_and_vec();
assert_eq!(a, v[..]);
}
}
================================================
FILE: assets/rustlings-zh/exercises/collections/vec2.rs
================================================
// vec2.rs
// 给定一个全是偶数的 Vec 。你的任务是完成一个循环,做到将 Vec 中的每个数字都乘以 2 。
//
// 让我通过编译和测试!
//
// 如果需要提示,可以执行命令 `rustlings hint vec2`。
// I AM NOT DONE
fn vec_loop(mut v: Vec<i32>) -> Vec<i32> {
for i in v.iter_mut() {
// TODO:将 Vec `v` 中的每个元素都乘以 2 。
}
// 此时 `v' 应该等于 [4, 8, 12, 16, 20] 。
v
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_vec_loop() {
let v: Vec<i32> = (1..).filter(|x| x % 2 == 0).take(5).collect();
let ans = vec_loop(v.clone());
assert_eq!(ans, v.iter().map(|x| x * 2).collect::<Vec<i32>>());
}
}
================================================
FILE: assets/rustlings-zh/exercises/conversions/README.md
================================================
# Type conversions
Rust offers a multitude of ways to convert a value of a given type into another type.
The simplest form of type conversion is a type cast expression. It is denoted with the binary operator `as`. For instance, `println!("{}", 1 + 1.0);` would not compile, since `1` is an integer while `1.0` is a float. However, `println!("{}", 1 as f32 + 1.0)` should compile. The exercise [`using_as`](using_as.rs) tries to cover this.
Rust also offers traits that facilitate type conversions upon implementation. These traits can be found under the [`convert`](https://doc.rust-lang.org/std/convert/index.html) module.
The traits are the following:
- `From` and `Into` covered in [`from_into`](from_into.rs)
- `TryFrom` and `TryInto` covered in [`try_from_into`](try_from_into.rs)
- `AsRef` and `AsMut` covered in [`as_ref_mut`](as_ref_mut.rs)
Furthermore, the `std::str` module offers a trait called [`FromStr`](https://doc.rust-lang.org/std/str/trait.FromStr.html) which helps with converting strings into target types via the `parse` method on strings. If properly implemented for a given type `Person`, then `let p: Person = "Mark,20".parse().unwrap()` should both compile and run without panicking.
These should be the main ways ***within the standard library*** to convert data into your desired types.
## Further information
These are not directly covered in the book, but the standard library has a great documentation for it.
- [conversions](https://doc.rust-lang.org/std/convert/index.html)
- [`FromStr` trait](https://doc.rust-lang.org/std/str/trait.FromStr.html)
================================================
FILE: assets/rustlings-zh/exercises/conversions/as_ref_mut.rs
================================================
// AsRef and AsMut allow for cheap reference-to-reference conversions.
// Read more about them at https://doc.rust-lang.org/std/convert/trait.AsRef.html
// and https://doc.rust-lang.org/std/convert/trait.AsMut.html, respectively.
// I AM NOT DONE
// Obtain the number of bytes (not characters) in the given argument
// Add the AsRef trait appropriately as a trait bound
fn byte_counter<T>(arg: T) -> usize {
arg.as_ref().as_bytes().len()
}
// Obtain the number of characters (not bytes) in the given argument
// Add the AsRef trait appropriately as a trait bound
fn char_counter<T>(arg: T) -> usize {
arg.as_ref().chars().count()
}
fn main() {
let s = "Café au lait";
println!("{}", char_counter(s));
println!("{}", byte_counter(s));
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn different_counts() {
let s = "Café au lait";
assert_ne!(char_counter(s), byte_counter(s));
}
#[test]
fn same_counts() {
let s = "Cafe au lait";
assert_eq!(char_counter(s), byte_counter(s));
}
#[test]
fn different_counts_using_string() {
let s = String::from("Café au lait");
assert_ne!(char_counter(s.clone()), byte_counter(s));
}
#[test]
fn same_counts_using_string() {
let s = String::from("Cafe au lait");
assert_eq!(char_counter(s.clone()), byte_counter(s));
}
}
================================================
FILE: assets/rustlings-zh/exercises/conversions/from_into.rs
================================================
// The From trait is used for value-to-value conversions.
// If From is implemented correctly for a type, the Into trait should work conversely.
// You can read more about it at https://doc.rust-lang.org/std/convert/trait.From.html
#[derive(Debug)]
struct Person {
name: String,
age: usize,
}
// We implement the Default trait to use it as a fallback
// when the provided string is not convertible into a Person object
impl Default for Person {
fn default() -> Person {
Person {
name: String::from("John"),
age: 30,
}
}
}
// Your task is to complete this implementation
// in order for the line `let p = Person::from("Mark,20")` to compile
// Please note that you'll need to parse the age component into a `usize`
// with something like `"4".parse::<usize>()`. The outcome of this needs to
// be handled appropriately.
//
// Steps:
// 1. If the length of the provided string is 0, then return the default of Person
// 2. Split the given string on the commas present in it
// 3. Extract the first element from the split operation and use it as the name
// 4. If the name is empty, then return the default of Person
// 5. Extract the other element from the split operation and parse it into a `usize` as the age
// If while parsing the age, something goes wrong, then return the default of Person
// Otherwise, then return an instantiated Person object with the results
// I AM NOT DONE
impl From<&str> for Person {
fn from(s: &str) -> Person {
}
}
fn main() {
// Use the `from` function
let p1 = Person::from("Mark,20");
// Since From is implemented for Person, we should be able to use Into
let p2: Person = "Gerald,70".into();
println!("{:?}", p1);
println!("{:?}", p2);
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_default() {
// Test that the default person is 30 year old John
let dp = Person::default();
assert_eq!(dp.name, "John");
assert_eq!(dp.age, 30);
}
#[test]
fn test_bad_convert() {
// Test that John is returned when bad string is provided
let p = Person::from("");
assert_eq!(p.name, "John");
assert_eq!(p.age, 30);
}
#[test]
fn test_good_convert() {
// Test that "Mark,20" works
let p = Person::from("Mark,20");
assert_eq!(p.name, "Mark");
assert_eq!(p.age, 20);
}
#[test]
fn test_bad_age() {
// Test that "Mark,twenty" will return the default person due to an error in parsing age
let p = Person::from("Mark,twenty");
assert_eq!(p.name, "John");
assert_eq!(p.age, 30);
}
#[test]
fn test_missing_comma_and_age() {
let p: Person = Person::from("Mark");
assert_eq!(p.name, "John");
assert_eq!(p.age, 30);
}
#[test]
fn test_missing_age() {
let p: Person = Person::from("Mark,");
assert_eq!(p.name, "John");
assert_eq!(p.age, 30);
}
#[test]
fn test_missing_name() {
let p: Person = Person::from(",1");
assert_eq!(p.name, "John");
assert_eq!(p.age, 30);
}
#[test]
fn test_missing_name_and_age() {
let p: Person = Person::from(",");
assert_eq!(p.name, "John");
assert_eq!(p.age, 30);
}
#[test]
fn test_missing_name_and_invalid_age() {
let p: Person = Person::from(",one");
assert_eq!(p.name, "John");
assert_eq!(p.age, 30);
}
#[test]
fn test_trailing_comma() {
let p: Person = Person::from("Mike,32,");
assert_eq!(p.name, "John");
assert_eq!(p.age, 30);
}
#[test]
fn test_trailing_comma_and_some_string() {
let p: Person = Person::from("Mike,32,man");
assert_eq!(p.name, "John");
assert_eq!(p.age, 30);
}
}
================================================
FILE: assets/rustlings-zh/exercises/conversions/from_str.rs
================================================
// from_str.rs
// This is similar to from_into.rs, but this time we'll implement `FromStr`
// and return errors instead of falling back to a default value.
// Additionally, upon implementing FromStr, you can use the `parse` method
// on strings to generate an object of the implementor type.
// You can read more about it at https://doc.rust-lang.org/std/str/trait.FromStr.html
use std::num::ParseIntError;
use std::str::FromStr;
#[derive(Debug, PartialEq)]
struct Person {
name: String,
age: usize,
}
// We will use this error type for the `FromStr` implementation.
#[derive(Debug, PartialEq)]
enum ParsePersonError {
// Empty input string
Empty,
// Incorrect number of fields
BadLen,
// Empty name field
NoName,
// Wrapped error from parse::<usize>()
ParseInt(ParseIntError),
}
// I AM NOT DONE
// Steps:
// 1. If the length of the provided string is 0, an error should be returned
// 2. Split the given string on the commas present in it
// 3. Only 2 elements should be returned from the split, otherwise return an error
// 4. Extract the first element from the split operation and use it as the name
// 5. Extract the other element from the split operation and parse it into a `usize` as the age
// with something like `"4".parse::<usize>()`
// 6. If while extracting the name and the age something goes wrong, an error should be returned
// If everything goes well, then return a Result of a Person object
impl FromStr for Person {
type Err = ParsePersonError;
fn from_str(s: &str) -> Result<Person, Self::Err> {
}
}
fn main() {
let p = "Mark,20".parse::<Person>().unwrap();
println!("{:?}", p);
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn empty_input() {
assert_eq!("".parse::<Person>(), Err(ParsePersonError::Empty));
}
#[test]
fn good_input() {
let p = "John,32".parse::<Person>();
assert!(p.is_ok());
let p = p.unwrap();
assert_eq!(p.name, "John");
assert_eq!(p.age, 32);
}
#[test]
fn missing_age() {
assert!(matches!(
"John,".parse::<Person>(),
Err(ParsePersonError::ParseInt(_))
));
}
#[test]
fn invalid_age() {
assert!(matches!(
"John,twenty".parse::<Person>(),
Err(ParsePersonError::ParseInt(_))
));
}
#[test]
fn missing_comma_and_age() {
assert_eq!("John".parse::<Person>(), Err(ParsePersonError::BadLen));
}
#[test]
fn missing_name() {
assert_eq!(",1".parse::<Person>(), Err(ParsePersonError::NoName));
}
#[test]
fn missing_name_and_age() {
assert!(matches!(
",".parse::<Person>(),
Err(ParsePersonError::NoName | ParsePersonError::ParseInt(_))
));
}
#[test]
fn missing_name_and_invalid_age() {
assert!(matches!(
",one".parse::<Person>(),
Err(ParsePersonError::NoName | ParsePersonError::ParseInt(_))
));
}
#[test]
fn trailing_comma() {
assert_eq!("John,32,".parse::<Person>(), Err(ParsePersonError::BadLen));
}
#[test]
fn trailing_comma_and_some_string() {
assert_eq!(
"John,32,man".parse::<Person>(),
Err(ParsePersonError::BadLen)
);
}
}
================================================
FILE: assets/rustlings-zh/exercises/conversions/try_from_into.rs
================================================
// try_from_into.rs
// TryFrom is a simple and safe type conversion that may fail in a controlled way under some circumstances.
// Basically, this is the same as From. The main difference is that this should return a Result type
// instead of the target type itself.
// You can read more about it at https://doc.rust-lang.org/std/convert/trait.TryFrom.html
use std::convert::{TryFrom, TryInto};
#[derive(Debug, PartialEq)]
struct Color {
red: u8,
green: u8,
blue: u8,
}
// We will use this error type for these `TryFrom` conversions.
#[derive(Debug, PartialEq)]
enum IntoColorError {
// Incorrect length of slice
BadLen,
// Integer conversion error
IntConversion,
}
// I AM NOT DONE
// Your task is to complete this implementation
// and return an Ok result of inner type Color.
// You need to create an implementation for a tuple of three integers,
// an array of three integers, and a slice of integers.
//
// Note that the implementation for tuple and array will be checked at compile time,
// but the slice implementation needs to check the slice length!
// Also note that correct RGB color values must be integers in the 0..=255 range.
// Tuple implementation
impl TryFrom<(i16, i16, i16)> for Color {
type Error = IntoColorError;
fn try_from(tuple: (i16, i16, i16)) -> Result<Self, Self::Error> {
}
}
// Array implementation
impl TryFrom<[i16; 3]> for Color {
type Error = IntoColorError;
fn try_from(arr: [i16; 3]) -> Result<Self, Self::Error> {
}
}
// Slice implementation
impl TryFrom<&[i16]> for Color {
type Error = IntoColorError;
fn try_from(slice: &[i16]) -> Result<Self, Self::Error> {
}
}
fn main() {
// Use the `from` function
let c1 = Color::try_from((183, 65, 14));
println!("{:?}", c1);
// Since TryFrom is implemented for Color, we should be able to use TryInto
let c2: Result<Color, _> = [183, 65, 14].try_into();
println!("{:?}", c2);
let v = vec![183, 65, 14];
// With slice we should use `try_from` function
let c3 = Color::try_from(&v[..]);
println!("{:?}", c3);
// or take slice within round brackets and use TryInto
let c4: Result<Color, _> = (&v[..]).try_into();
println!("{:?}", c4);
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_tuple_out_of_range_positive() {
assert_eq!(
Color::try_from((256, 1000, 10000)),
Err(IntoColorError::IntConversion)
);
}
#[test]
fn test_tuple_out_of_range_negative() {
assert_eq!(
Color::try_from((-1, -10, -256)),
Err(IntoColorError::IntConversion)
);
}
#[test]
fn test_tuple_sum() {
assert_eq!(
Color::try_from((-1, 255, 255)),
Err(IntoColorError::IntConversion)
);
}
#[test]
fn test_tuple_correct() {
let c: Result<Color, _> = (183, 65, 14).try_into();
assert!(c.is_ok());
assert_eq!(
c.unwrap(),
Color {
red: 183,
green: 65,
blue: 14
}
);
}
#[test]
fn test_array_out_of_range_positive() {
let c: Result<Color, _> = [1000, 10000, 256].try_into();
assert_eq!(c, Err(IntoColorError::IntConversion));
}
#[test]
fn test_array_out_of_range_negative() {
let c: Result<Color, _> = [-10, -256, -1].try_into();
assert_eq!(c, Err(IntoColorError::IntConversion));
}
#[test]
fn test_array_sum() {
let c: Result<Color, _> = [-1, 255, 255].try_into();
assert_eq!(c, Err(IntoColorError::IntConversion));
}
#[test]
fn test_array_correct() {
let c: Result<Color, _> = [183, 65, 14].try_into();
assert!(c.is_ok());
assert_eq!(
c.unwrap(),
Color {
red: 183,
green: 65,
blue: 14
}
);
}
#[test]
fn test_slice_out_of_range_positive() {
let arr = [10000, 256, 1000];
assert_eq!(
Color::try_from(&arr[..]),
Err(IntoColorError::IntConversion)
);
}
#[test]
fn test_slice_out_of_range_negative() {
let arr = [-256, -1, -10];
assert_eq!(
Color::try_from(&arr[..]),
Err(IntoColorError::IntConversion)
);
}
#[test]
fn test_slice_sum() {
let arr = [-1, 255, 255];
assert_eq!(
Color::try_from(&arr[..]),
Err(IntoColorError::IntConversion)
);
}
#[test]
fn test_slice_correct() {
let v = vec![183, 65, 14];
let c: Result<Color, _> = Color::try_from(&v[..]);
assert!(c.is_ok());
assert_eq!(
c.unwrap(),
Color {
red: 183,
green: 65,
blue: 14
}
);
}
#[test]
fn test_slice_excess_length() {
let v = vec![0, 0, 0, 0];
assert_eq!(Color::try_from(&v[..]), Err(IntoColorError::BadLen));
}
#[test]
fn test_slice_insufficient_length() {
let v = vec![0, 0];
assert_eq!(Color::try_from(&v[..]), Err(IntoColorError::BadLen));
}
}
================================================
FILE: assets/rustlings-zh/exercises/conversions/using_as.rs
================================================
// Type casting in Rust is done via the usage of the `as` operator.
// Please note that the `as` operator is not only used when type casting.
// It also helps with renaming imports.
//
// The goal is to make sure that the division does not fail to compile
// and returns the proper type.
// I AM NOT DONE
fn average(values: &[f64]) -> f64 {
let total = values.iter().fold(0.0, |a, b| a + b);
total / values.len()
}
fn main() {
let values = [3.5, 0.3, 13.0, 11.7];
println!("{}", average(&values));
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn returns_proper_type_and_value() {
assert_eq!(average(&[3.5, 0.3, 13.0, 11.7]), 7.125);
}
}
================================================
FILE: assets/rustlings-zh/exercises/enums/README.md
================================================
# 枚举(enums)
Rust 有一种叫做“枚举”的类型,这种类型列举出了某种集合中所有可能的值。
枚举是许多语言共有的一个功能,但它的作用在每种语言中都有所不同。
如 F#、OCaml 和 Haskell 之类的函数式语言中的代数数据类型(algebraic data types)和 Rust 的枚举很相似。
Rust 的“模式匹配”功能与枚举结合起非常强大,利用它我们很容易就能针对枚举的不同类型运行不同的代码。
## 更多信息
- [Enums](https://doc.rust-lang.org/book/ch06-00-enums.html)
- [Pattern syntax](https://doc.rust-lang.org/book/ch18-03-pattern-syntax.html)
================================================
FILE: assets/rustlings-zh/exercises/enums/enums1.rs
================================================
// enums1.rs
// 让我能够编译!执行 `rustex hint enums1` 获取提示 :)
// I AM NOT DONE
#[derive(Debug)]
enum Message {
// TODO:遵照下面的使用方式来定义几种 Message 的类型
}
fn main() {
println!("{:?}", Message::Quit);
println!("{:?}", Message::Echo);
println!("{:?}", Message::Move);
println!("{:?}", Message::ChangeColor);
}
================================================
FILE: assets/rustlings-zh/exercises/enums/enums2.rs
================================================
// enums2.rs
// 让我能够编译!执行 `rustex hint enums2` 获取提示!
// I AM NOT DONE
#[derive(Debug)]
enum Message {
// TODO:定义下面使用到的多种 Message 类型
}
impl Message {
fn call(&self) {
println!("{:?}", &self);
}
}
fn main() {
let messages = [
Message::Move { x: 10, y: 30 },
Message::Echo(String::from("hello world")),
Message::ChangeColor(200, 255, 255),
Message::Quit,
];
for message in &messages {
message.call();
}
}
================================================
FILE: assets/rustlings-zh/exercises/enums/enums3.rs
================================================
// enums3.rs
// 解决所有的 TODO ,通过测试!
// I AM NOT DONE
enum Message {
// TODO:根据以下的使用方式,实现 Message 的不同类型
}
struct Point {
x: u8,
y: u8,
}
struct State {
color: (u8, u8, u8),
position: Point,
quit: bool,
}
impl State {
fn change_color(&mut self, color: (u8, u8, u8)) {
self.color = color;
}
fn quit(&mut self) {
self.quit = true;
}
fn echo(&self, s: String) {
println!("{}", s);
}
fn move_position(&mut self, p: Point) {
self.position = p;
}
fn process(&mut self, message: Message) {
// TODO:使用 match 表达式来处理不同类型的消息
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_match_message_call() {
let mut state = State {
quit: false,
position: Point { x: 0, y: 0 },
color: (0, 0, 0),
};
state.process(Message::ChangeColor((255, 0, 255)));
state.process(Message::Echo(String::from("hello world")));
state.process(Message::Move(Point { x: 10, y: 15 }));
state.process(Message::Quit);
assert_eq!(state.color, (255, 0, 255));
assert_eq!(state.position.x, 10);
assert_eq!(state.position.y, 15);
assert_eq!(state.quit, true);
}
}
================================================
FILE: assets/rustlings-zh/exercises/error_handling/README.md
================================================
# 错误处理
大多数的错误并没有严重到需要让程序完全停止运行的程度。
有时一个函数执行失败时,你可以很容易地对造成失败的原因进行解释并采取对应措施的。
例如,你正试图打开一个文件,但由于该文件不存在导致了操作失败,这时你可能想创建
该文件而不是直接终止程序。
## 更多信息
- [Error Handling](https://doc.rust-lang.org/book/ch09-02-recoverable-errors-with-result.html)
- [Generics](https://doc.rust-lang.org/book/ch10-01-syntax.html)
- [Result](https://doc.rust-lang.org/rust-by-example/error/result.html)
- [Boxing errors](https://doc.rust-lang.org/rust-by-example/error/multiple_error_types/boxing_errors.html)
================================================
FILE: assets/rustlings-zh/exercises/error_handling/errors1.rs
================================================
// errors1.rs
// 假使你传给这个函数一个空字符串,那么它将拒绝生成一段个性签名(nametage)。
// 如果它能解释拒绝的原因是什么,而不是粗暴返回 `None` 那就更完美了。
// 第 2 个测试目前还没通过并未能编译,但它说明了我们希望这个函数具有的行为。
// 执行 `rustlings hint errors1` 获取提示!
// I AM NOT DONE
pub fn generate_nametag_text(name: String) -> Option<String> {// 译:生成个性签名
if name.len() > 0 {
Some(format!("Hi! My name is {}", name))// 译:"嗨!我的名字是 {}"
} else {
// 不允许使用空的名字。
None
}
}
#[cfg(test)]
mod tests {
use super::*;
// 你可以注释掉第 2 个测试,那么这个测试就能初步通过。
// 当你更改了测试的函数时,也需要修改下测试代码以使测试正确!
#[test]
fn generates_nametag_text_for_a_nonempty_name() {// 译:用一个非空名称生成一段个性签名
assert_eq!(
generate_nametag_text("Beyoncé".into()),
Some("Hi! My name is Beyoncé".into())
);
}
#[test]
fn explains_why_generating_nametag_text_fails() {// 译:说明为什么个性签名生成失败了
assert_eq!(
generate_nametag_text("".into()),
Err("`name` was empty; it must be nonempty.".into())
);
}
}
================================================
FILE: assets/rustlings-zh/exercises/error_handling/errors2.rs
================================================
// errors2.rs
// 假设我们正在编写一个游戏,你可以用代币购买物品。
// 所有物品的价格都是 5 个代币,每当你购买物品时,都需要 1 个代币的小费。
// 游戏玩家将输入他们想要购买的物品数量,`total_cost` 函数能够计算出所需的代币数量。
// 虽然玩家输入的是数量,但我们得到的却是一个字符串——他们可能输入了任何东西,而不仅仅是数字!
// 目前这个函数没有处理任何错误的情况(也没有处理成功的情况)。
// 我们要做的是:
// 如果我们在非数字的字符串上调用 `parse` 方法,该方法将返回 `ParseIntError`,
// 在这种情况下,我们要立刻从函数返回这个错误,而不是继续进行相关计算。
// 至少有两种方法可以做到这点,它们都是正确的——但其中一种简短得多!
// 执行 `rustlings hint errors2` 以获得关于这两种方式的提示。
// I AM NOT DONE
use std::num::ParseIntError;
pub fn total_cost(item_quantity: &str) -> Result<i32, ParseIntError> {
let processing_fee = 1;
let cost_per_item = 5;
let qty = item_quantity.parse::<i32>();
Ok(qty * cost_per_item + processing_fee)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn item_quantity_is_a_valid_number() {
assert_eq!(total_cost("34"), Ok(171));
}
#[test]
fn item_quantity_is_an_invalid_number() {
assert_eq!(
total_cost("beep boop").unwrap_err().to_string(),
"invalid digit found in string"
);// 译:字符串中包含无效的数字
}
}
================================================
FILE: assets/rustlings-zh/exercises/error_handling/errors3.rs
================================================
// errors3.rs
// 这是一个试图使用前面练习中 `total_cost` 函数完整版的程序。
// 但出了些问题!为什么不行?我们需要怎样做才能解决问题?
// 执行 `rustlings hint errors3` 获取提示!
// I AM NOT DONE
use std::num::ParseIntError;
fn main() {
let mut tokens = 100;
let pretend_user_input = "8";
let cost = total_cost(pretend_user_input)?;
if cost > tokens {
println!("You can't afford that many!");// 译:你的代币不足以完成支付!
} else {
tokens -= cost;
println!("You now have {} tokens.", tokens);// 译:现在你有 {} 个代币"
}
}
pub fn total_cost(item_quantity: &str) -> Result<i32, ParseIntError> {
let processing_fee = 1;
let cost_per_item = 5;
let qty = item_quantity.parse::<i32>()?;
Ok(qty * cost_per_item + processing_fee)
}
================================================
FILE: assets/rustlings-zh/exercises/error_handling/errors4.rs
================================================
// errors4.rs
// 通过测试!执行 `rustlings hint errors4` 获取提示 :)
// I AM NOT DONE
#[derive(PartialEq, Debug)]
struct PositiveNonzeroInteger(u64);
#[derive(PartialEq, Debug)]
enum CreationError {
Negative,
Zero,
}
impl PositiveNonzeroInteger {
fn new(value: i64) -> Result<PositiveNonzeroInteger, CreationError> {
Ok(PositiveNonzeroInteger(value as u64))
}
}
#[test]
fn test_creation() {
assert!(PositiveNonzeroInteger::new(10).is_ok());
assert_eq!(
Err(CreationError::Negative),
PositiveNonzeroInteger::new(-10)
);
assert_eq!(Err(CreationError::Zero), PositiveNonzeroInteger::new(0));
}
================================================
FILE: assets/rustlings-zh/exercises/error_handling/errors5.rs
================================================
// errors5.rs
// 这个程序使用练习 errors4 代码的完整版。
// 它现在不能编译! 为什么呢?
// 执行 `rustlings hint errors5` 获取提示!
// I AM NOT DONE
use std::error;
use std::fmt;
use std::num::ParseIntError;
// TODO:修改 `main()` 的返回类型,以使其通过编译。
fn main() -> Result<(), ParseIntError> {
let pretend_user_input = "42";
let x: i64 = pretend_user_input.parse()?;
println!("output={:?}", PositiveNonzeroInteger::new(x)?);
Ok(())
}
// 不要更改此行以下的任何内容。
#[derive(PartialEq, Debug)]
struct PositiveNonzeroInteger(u64);
#[derive(PartialEq, Debug)]
enum CreationError {
Negative,
Zero,
}
impl PositiveNonzeroInteger {
fn new(value: i64) -> Result<PositiveNonzeroInteger, CreationError> {
match value {
x if x < 0 => Err(CreationError::Negative),
x if x == 0 => Err(CreationError::Zero),
x => Ok(PositiveNonzeroInteger(x as u64))
}
}
}
// 以下是必要的,以便 `CreationError` 能够实现 `error::Error` 。
impl fmt::Display for CreationError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let description = match *self {
CreationError::Negative => "number is negative",
CreationError::Zero => "number is zero",
};
f.write_str(description)
}
}
impl error::Error for CreationError {}
================================================
FILE: assets/rustlings-zh/exercises/error_handling/errors6.rs
================================================
// errors6.rs
// 像 `Box<dyn error::Error>` 这样的万能错误类型并不推荐用于库代码,
// 因为调用者可能想根据错误内容进行相关处理,而不是将其打印出来或进一步传播。
// 在这里,我们自定义了一个错误类型,让调用者有可能去决定当函数返回错误时
// 下一步该怎么做
// 通过这些测试!执行 `rustlings hint errors6` 获取提示 :)
// I AM NOT DONE
use std::num::ParseIntError;
// 这是一个自定义的错误类型,我们将在 `parse_pos_nonzero()` 中使用。
#[derive(PartialEq, Debug)]
enum ParsePosNonzeroError {
Creation(CreationError),
ParseInt(ParseIntError)
}
impl ParsePosNonzeroError {
fn from_creation(err: CreationError) -> ParsePosNonzeroError {
ParsePosNonzeroError::Creation(err)
}
// TODO:在这添加另一个错误转换函数。
}
fn parse_pos_nonzero(s: &str)
-> Result<PositiveNonzeroInteger, ParsePosNonzeroError>
{
// TODO:改为返回一个恰当的错误,而不是在 `parse()` 返回一个错误时 panic
let x: i64 = s.parse().unwrap();
PositiveNonzeroInteger::new(x)
.map_err(ParsePosNonzeroError::from_creation)
}
// 不要更改这一行以下的任何内容。
#[derive(PartialEq, Debug)]
struct PositiveNonzeroInteger(u64);
#[derive(PartialEq, Debug)]
enum CreationError {
Negative,
Zero,
}
impl PositiveNonzeroInteger {
fn new(value: i64) -> Result<PositiveNonzeroInteger, CreationError> {
match value {
x if x < 0 => Err(CreationError::Negative),
x if x == 0 => Err(CreationError::Zero),
x => Ok(PositiveNonzeroInteger(x as u64))
}
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_parse_error() {
// 我们不能构造一个 ParseIntError ,所以必须进行模式匹配。
assert!(matches!(
parse_pos_nonzero("not a number"),
Err(ParsePosNonzeroError::ParseInt(_))
));
}
#[test]
fn test_negative() {
assert_eq!(
parse_pos_nonzero("-555"),
Err(ParsePosNonzeroError::Creation(CreationError::Negative))
);
}
#[test]
fn test_zero() {
assert_eq!(
parse_pos_nonzero("0"),
Err(ParsePosNonzeroError::Creation(CreationError::Zero))
);
}
#[test]
fn test_positive() {
let x = PositiveNonzeroInteger::new(42);
assert!(x.is_ok());
assert_eq!(parse_pos_nonzero("42"), Ok(x.unwrap()));
}
}
================================================
FILE: assets/rustlings-zh/exercises/functions/README.md
================================================
# 函数(Functions)
在本练习,你将学习如何编写一个函数,以及 Rust 编译器怎样可以对事物进行追溯(trace things way back)。
译:依据练习的内容,追溯的意思可能是类型推导之类的事。
## 更多信息
- [How Functions Work](https://doc.rust-lang.org/book/ch03-03-how-functions-work.html)
================================================
FILE: assets/rustlings-zh/exercises/functions/functions1.rs
================================================
// functions1.rs
// 让我能够编译!执行 `rustex hint functions1` 获取提示 :)
// I AM NOT DONE
/// 翻译: [mg-chao](https://github.com/mg-chao)
fn main() {
call_me();
}
================================================
FILE: assets/rustlings-zh/exercises/functions/functions2.rs
================================================
// functions2.rs
// 让我能够编译!执行 `rustex hint functions2` 获取提示 :)
// I AM NOT DONE
/// 翻译: [mg-chao](https://github.com/mg-chao)
fn main() {
call_me(3);
}
fn call_me(num:) {
for i in 0..num {
println!("Ring! Call number {}", i + 1);// 译:"叮!呼叫号码 {}"
}
}
================================================
FILE: assets/rustlings-zh/exercises/functions/functions3.rs
================================================
// functions3.rs
// 让我能够编译!执行 `rustex hint functions3` 获取提示 :)
// I AM NOT DONE
/// 翻译: [mg-chao](https://github.com/mg-chao)
fn main() {
call_me();
}
fn call_me(num: u32) {
for i in 0..num {
println!("Ring! Call number {}", i + 1);
}
}
================================================
FILE: assets/rustlings-zh/exercises/functions/functions4.rs
================================================
// functions4.rs
// 让我能够编译!执行 `rustex hint functions4` 获取提示 :)
// 商店正在进行促销,如果价格是偶数,可以优惠 10 Rustbucks,如果是奇数,则优惠 3 Rustbucks。
// 译:Rustbucks 可能想表达 Rust元 的意思,好比 美元 。
// I AM NOT DONE
/// 翻译: [mg-chao](https://github.com/mg-chao)
fn main() {
let original_price = 51;
println!("Your sale price is {}", sale_price(original_price));// 译:"你需支付 {}"
}
fn sale_price(price: i32) -> {
if is_even(price) {
price - 10
} else {
price - 3
}
}
fn is_even(num: i32) -> bool {
num % 2 == 0
}
================================================
FILE: assets/rustlings-zh/exercises/functions/functions5.rs
================================================
// functions5.rs
// 让我能够编译!执行 `rustex hint functions5` 获取提示 :)
// I AM NOT DONE
/// 翻译: [mg-chao](https://github.com/mg-chao)
fn main() {
let answer = square(3);
println!("The answer is {}", answer);// 译:"答案是 {}"
}
fn square(num: i32) -> i32 {
num * num;
}
================================================
FILE: assets/rustlings-zh/exercises/generics/README.md
================================================
# 泛型
泛型的主旨是把类型和函数泛化到多种情况。
这在很多方面有助于减少重复代码,但也可能需要为此使用相当多的语法。
也就是说,使用泛型的话则需要小心谨慎地标明泛型适用于哪些类型。
## 更多信息
- [Generic Data Types](https://doc.rust-lang.org/stable/book/ch10-01-syntax.html)
- [Bounds](https://doc.rust-lang.org/rust-by-example/generics/bounds.html)
================================================
FILE: assets/rustlings-zh/exercises/generics/generics1.rs
================================================
// 这个购物清单程序无法编译!
// 用你对泛型的了解来解决这个问题。
// 执行 `rustlings hint generics1` 获取提示!
// I AM NOT DONE
fn main() {
let mut shopping_list: Vec<?> = Vec::new();
shopping_list.push("milk");
}
================================================
FILE: assets/rustlings-zh/exercises/generics/generics2.rs
================================================
// 这个强大的 Wrapper 拥有存储一个正整数值的能力。
// 利用泛型重写它,使它支持包装(wrapping)任何类型的值。
// 执行 `rustlings hint generics2` 获取提示!
// I AM NOT DONE
struct Wrapper {
value: u32,
}
impl Wrapper {
pub fn new(value: u32) -> Self {
Wrapper { value }
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn store_u32_in_wrapper() {
assert_eq!(Wrapper::new(42).value, 42);
}
#[test]
fn store_str_in_wrapper() {
assert_eq!(Wrapper::new("Foo").value, "Foo");
}
}
================================================
FILE: assets/rustlings-zh/exercises/generics/generics3.rs
================================================
// 一所想象的魔法学院有一个采用 Rust 编写的新版成绩单生成系统!
// 目前该系统仅支持创建以数字表示的成绩单(如 1.0 -> 5.5)。
// 然而,学校也发布用字母表示的成绩(A+ -> F-),所以需要能够打印两种成绩单。
// 在 ReportCard 结构定义和 impl 块中进行必要的代码修改,以支持用字母表示的成绩单。
// 将第二个测试的 grade 改为 "A+",用来表明代码已允许按字母表示成绩。
// 执行 'rustlings hint generics3' 获取提示!
// I AM NOT DONE
pub struct ReportCard {
pub grade: f32,
pub student_name: String,
pub student_age: u8,
}
impl ReportCard {
pub fn print(&self) -> String {
format!("{} ({}) - achieved a grade of {}",// 译:{} ({}) - 成绩为 {}"
&self.student_name, &self.student_age, &self.grade)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn generate_numeric_report_card() {
let report_card = ReportCard {
grade: 2.1,
student_name: "Tom Wriggle".to_string(),
student_age: 12,
};
assert_eq!(
report_card.print(),
"Tom Wriggle (12) - achieved a grade of 2.1"
);
}
#[test]
fn generate_alphabetic_report_card() {
// TODO:完成练习后,在这里更改 grade 的值。
let report_card = ReportCard {
grade: 2.1,
student_name: "Gary Plotter".to_string(),
student_age: 11,
};
assert_eq!(
report_card.print(),
"Gary Plotter (11) - achieved a grade of A+"
);
}
}
================================================
FILE: assets/rustlings-zh/exercises/if/README.md
================================================
# If
你将在这学习最基本的控制流(control flow)——`if`
## 更多信息
- [Control Flow - if expressions](https://doc.rust-lang.org/book/ch03-05-control-flow.html#if-expressions)
================================================
FILE: assets/rustlings-zh/exercises/if/if1.rs
================================================
// if1.rs
// I AM NOT DONE
pub fn bigger(a: i32, b: i32) -> i32 {
// 完成这个返回更大数字的函数!
// 但不允许以下方式:
// - 调用其它函数
// - 额外变量
// 执行 `rustex hint if1` 获取提示
}
// 暂时不要在意它 :)
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn ten_is_bigger_than_eight() {
assert_eq!(10, bigger(10, 8));
}
#[test]
fn fortytwo_is_bigger_than_thirtytwo() {
assert_eq!(42, bigger(32, 42));
}
}
================================================
FILE: assets/rustlings-zh/exercises/if/if2.rs
================================================
// if2.rs
// 第一步:让我能够编译!
// 第二步:bar_for_fuzz 和 default_to_baz 可以通过测试!
// 执行 `rustex hint if2` 获取提示 :)
// I AM NOT DONE
pub fn fizz_if_foo(fizzish: &str) -> &str {
if fizzish == "fizz" {
"foo"
} else {
1
}
}
// 测试不需要更改。
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn foo_for_fizz() {
assert_eq!(fizz_if_foo("fizz"), "foo")
}
#[test]
fn bar_for_fuzz() {
assert_eq!(fizz_if_foo("fuzz"), "bar")
}
#[test]
fn default_to_baz() {
assert_eq!(fizz_if_foo("literally anything"), "baz")
}
}
================================================
FILE: assets/rustlings-zh/exercises/macros/README.md
================================================
# Macros
Rust's macro system is very powerful, but also kind of difficult to wrap your
head around. We're not going to teach you how to write your own fully-featured
macros. Instead, we'll show you how to use and create them.
## Further information
- [Macros](https://doc.rust-lang.org/book/ch19-06-macros.html)
- [The Little Book of Rust Macros](https://danielkeep.github.io/tlborm/book/index.html)
================================================
FILE: assets/rustlings-zh/exercises/macros/macros1.rs
================================================
// macros1.rs
// Make me compile! Execute `rustlings hint macros1` for hints :)
// I AM NOT DONE
macro_rules! my_macro {
() => {
println!("Check out my macro!");
};
}
fn main() {
my_macro();
}
================================================
FILE: assets/rustlings-zh/exercises/macros/macros2.rs
================================================
// macros2.rs
// Make me compile! Execute `rustlings hint macros2` for hints :)
// I AM NOT DONE
fn main() {
my_macro!();
}
macro_rules! my_macro {
() => {
println!("Check out my macro!");
};
}
================================================
FILE: assets/rustlings-zh/exercises/macros/macros3.rs
================================================
// macros3.rs
// Make me compile, without taking the macro out of the module!
// Execute `rustlings hint macros3` for hints :)
// I AM NOT DONE
mod macros {
macro_rules! my_macro {
() => {
println!("Check out my macro!");
};
}
}
fn main() {
my_macro!();
}
================================================
FILE: assets/rustlings-zh/exercises/macros/macros4.rs
================================================
// macros4.rs
// Make me compile! Execute `rustlings hint macros4` for hints :)
// I AM NOT DONE
macro_rules! my_macro {
() => {
println!("Check out my macro!");
}
($val:expr) => {
println!("Look at this other macro: {}", $val);
}
}
fn main() {
my_macro!();
my_macro!(7777);
}
================================================
FILE: assets/rustlings-zh/exercises/modules/README.md
================================================
# 模块(Modules)
这部分我们将向你介绍 Rust 的模块系统。
## 更多信息
- [The Module System](https://doc.rust-lang.org/book/ch07-00-managing-growing-projects-with-packages-crates-and-modules.html)
================================================
FILE: assets/rustlings-zh/exercises/modules/modules1.rs
================================================
// modules1.rs
// 让我能够编译!执行 `rustex hint modules1` 获取提示 :)
// I AM NOT DONE
mod sausage_factory {
// 确保它仅在当前模块可见。
fn get_secret_recipe() -> String {
String::from("Ginger")
}
fn make_sausage() {
get_secret_recipe();
println!("sausage!");
}
}
fn main() {
sausage_factory::make_sausage();
}
================================================
FILE: assets/rustlings-zh/exercises/modules/modules2.rs
================================================
// modules2.rs
// 你可以把模块引入作用域,并使用 'use' 和 'as' 关键字给它们取个别称.
// 修复 'use' 语句的相关代码以通过编译。
// 让我能够编译!执行 `rustex hint modules2` 获取提示 :)
// I AM NOT DONE
mod delicious_snacks {
// TODO: 修复这些 'use' 语句
use self::fruits::PEAR as ???
use self::veggies::CUCUMBER as ???
mod fruits {
pub const PEAR: &'static str = "Pear";
pub const APPLE: &'static str = "Apple";
}
mod veggies {
pub const CUCUMBER: &'static str = "Cucumber";
pub const CARROT: &'static str = "Carrot";
}
}
fn main() {
println!(
"favorite snacks: {} and {}",
delicious_snacks::fruit,
delicious_snacks::veggie
);
}
================================================
FILE: assets/rustlings-zh/exercises/modules/modules3.rs
================================================
// modules3.rs
// 你可以使用 'use' 关键字将任何位置的模块(特别是 Rust 标准库中的模块)引入作用域。
// 从 std::time 模块引入 SystemTime 和 UNIX_EPOCH。如果你能用一行代码解决,就能获得额外得分。
// 让我能够编译!执行 `rustex hint modules3` 获取提示 :)
// I AM NOT DONE
// TODO: 完成这个 `use` 语句
use ???
fn main() {
match SystemTime::now().duration_since(UNIX_EPOCH) {
Ok(n) => println!("1970-01-01 00:00:00 UTC was {} seconds ago!", n.as_secs()),
Err(_) => panic!("SystemTime before UNIX EPOCH!"),
}
}
================================================
FILE: assets/rustlings-zh/exercises/move_semantics/README.md
================================================
# 移动语义(Move Semantics)
这些练习改编自 [pnkfelix](https://github.com/pnkfelix) 的 [Rust Tutorial](https://pnkfelix.github.io/rust-examples-icfp2014/) -- 谢谢 Felix !!!
## 更多信息
以下书籍中的内容对于当前的学习尤其重要。
- [Ownership](https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html)
- [Reference and borrowing](https://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html)
================================================
FILE: assets/rustlings-zh/exercises/move_semantics/move_semantics1.rs
================================================
// move_semantics1.rs
// 让我能够编译!执行 `rustex hint move_semantics1` 获取提示 :)
// I AM NOT DONE
fn main() {
let vec0 = Vec::new();
let vec1 = fill_vec(vec0);
println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);// 译:"{} 长度为 {} 内容是 `{:?}`"
vec1.push(88);
println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);
}
fn fill_vec(vec: Vec<i32>) -> Vec<i32> {
let mut vec = vec;
vec.push(22);
vec.push(44);
vec.push(66);
vec
}
================================================
FILE: assets/rustlings-zh/exercises/move_semantics/move_semantics2.rs
================================================
// move_semantics2.rs
// 在不更改第 13 行的要求下通过编译!
// 执行 `rustex hint move_semantics2` 获取提示 :)
// I AM NOT DONE
fn main() {
let vec0 = Vec::new();
let mut vec1 = fill_vec(vec0);
// 不要更改下面那行!
println!("{} has length {} content `{:?}`", "vec0", vec0.len(), vec0);
vec1.push(88);
println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);
}
fn fill_vec(vec: Vec<i32>) -> Vec<i32> {
let mut vec = vec;
vec.push(22);
vec.push(44);
vec.push(66);
vec
}
================================================
FILE: assets/rustlings-zh/exercises/move_semantics/move_semantics3.rs
================================================
// move_semantics3.rs
// 在不添加新行仅改变已有行的要求下通过编译!
// (也不允许有多个分号的行!)
// 执行 `rustex hint move_semantics3` 获取提示 :)
// I AM NOT DONE
fn main() {
let vec0 = Vec::new();
let mut vec1 = fill_vec(vec0);
println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);
vec1.push(88);
println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);
}
fn fill_vec(vec: Vec<i32>) -> Vec<i32> {
vec.push(22);
vec.push(44);
vec.push(66);
vec
}
================================================
FILE: assets/rustlings-zh/exercises/move_semantics/move_semantics4.rs
================================================
// move_semantics4.rs
// 重构这段代码,做到删除 `vec0` ,并在 `fn fill_vec` 而非 `fn main` 中创建 vector ,
// 然后将新创建的 vector 从 `fill_vec` 转移到其调用者。
// 执行 `rustex hint move_semantics4` 获取提示 :)
// I AM NOT DONE
fn main() {
let vec0 = Vec::new();
let mut vec1 = fill_vec(vec0);
println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);
vec1.push(88);
println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);
}
// `fill_vec()` 不再获取 `vec: Vec<i32>` 参数
fn fill_vec() -> Vec<i32> {
let mut vec = vec;
vec.push(22);
vec.push(44);
vec.push(66);
vec
}
================================================
FILE: assets/rustlings-zh/exercises/move_semantics/move_semantics5.rs
================================================
// move_semantics5.rs
// 只通过重新排列 `main()` 中的已有行来完成编译,并且不能增加、更改或删除任何行
// 执行 `rustex hint move_semantics5` 获取提示 :)
// I AM NOT DONE
fn main() {
let mut x = 100;
let y = &mut x;
let z = &mut x;
*y += 100;
*z += 1000;
assert_eq!(x, 1200);
}
================================================
FILE: assets/rustlings-zh/exercises/option/README.md
================================================
# Option
Option 类型代表可选的值:每个 Option 要么是 Some ,包含一个值;要么是 None ,表示空值。
Option 在 Rust 代码中十分常见,因为它有许多用途:
- 初始值
- 输入值不符合定义的情况下作为函数的返回值(部分函数)。
- 返回 None 作为简单错误的返回值
- 可选的结构字段
- 可以借用或 "取走" 的结构字段(的值)
- 可选的函数参数
- 空指针
- 在某些情况下交换值*
译注:“在某些情况下交换值”可以假设有个可变数组,现在要通过两个可变引用来交换其中两个元素的值。但 Rust 显然不允许有两个对数组的可变引用,这时候可以用 Option 包装下元素值,比如:
``` rust
fn main() {
let mut array = vec![Some(1), Some(2)];
let a = array.get_mut(0).unwrap().take().unwrap();
let b = array.get_mut(1).unwrap().replace(a);
*array.get_mut(0).unwrap() = b;
println!("{:?}", array);// [Some(2), Some(1)]
}
```
嘿嘿,有点强行了。
[示例参考](https://zulip-archive.rust-lang.org/stream/122651-general/topic/.60Option.60.20.22swapping.20things.20out.20of.20difficult.20situations.22.3F.html)
[关于 Option 的描述来自于](https://doc.rust-lang.org/std/option/)
## 更多信息
- [Option Enum Format](https://doc.rust-lang.org/stable/book/ch10-01-syntax.html#in-enum-definitions)
- [Option Module Documentation](https://doc.rust-lang.org/std/option/)
- [Option Enum Documentation](https://doc.rust-lang.org/std/option/enum.Option.html)
================================================
FILE: assets/rustlings-zh/exercises/option/option1.rs
================================================
// option1.rs
// 让我通过编译!执行 `rustlings hint option1` 获取提示!
// I AM NOT DONE
// 你可以自由修改代码,但这个函数签名除外。
fn print_number(maybe_number: Option<u16>) {
println!("printing: {}", maybe_number.unwrap());
}
fn main() {
print_number(13);
print_number(99);
let mut numbers: [Option<u16>; 5];
for iter in 0..5 {
let number_to_add: u16 = {
((iter * 1235) + 2) / (4 * 16)
};
numbers[iter as usize] = number_to_add;
}
}
================================================
FILE: assets/rustlings-zh/exercises/option/option2.rs
================================================
// option2.rs
// 让我通过编译!执行 `rustlings hint option2` 获取提示!
// I AM NOT DONE
fn main() {
let optional_word = Some(String::from("rustlings"));
// TODO:改成适用于值为 "Some" 类型的 if let 语句,
word = optional_word {
println!("The word is: {}", word);
} else {
println!("The optional word doesn't contain anything");
}
let mut optional_integers_vec: Vec<Option<i8>> = Vec::new();
for x in 1..10 {
optional_integers_vec.push(Some(x));
}
// TODO:改成 while let 语句——记住,vector.pop 的返回类型为 Option<T>。
// 你可以多次层叠地对 `Option<T>` 使用 while let 或 if let
integer = optional_integers_vec.pop() {
println!("current value: {}", integer);
}
}
================================================
FILE: assets/rustlings-zh/exercises/option/option3.rs
================================================
// option3.rs
// 让我通过编译!执行 `rustlings hint option3` 获取提示
// I AM NOT DONE
struct Point {
x: i32,
y: i32,
}
fn main() {
let y: Option<Point> = Some(Point { x: 100, y: 200 });
match y {
Some(p) => println!("Co-ordinates are {},{} ", p.x, p.y),
_ => println!("no match"),
}
y; // 无需删除这行就可以解决。
}
================================================
FILE: assets/rustlings-zh/exercises/primitive_types/README.md
================================================
# 基本类型(Primitive Types)
Rust 有几个直接在编译器中实现基本类型。在本节中,我们来看看最重要的几个。
## 更多信息
- [Data Types](https://doc.rust-lang.org/stable/book/ch03-02-data-types.html)
- [The Slice Type](https://doc.rust-lang.org/stable/book/ch04-03-slices.html)
================================================
FILE: assets/rustlings-zh/exercises/primitive_types/primitive_types1.rs
================================================
// primitive_types1.rs
// 补充不完整代码行的缺失部分!
// 没有提示,也没有什么诀窍,只要习惯于键入这些内容就可以了 :)
// I AM NOT DONE
fn main() {
// Booleans (`bool`)
let is_morning = true;
if is_morning {
println!("Good morning!");// 译:"早上好"
}
let // 参照上面的示例来补充这一行的缺失部分!或者让它值为 false !
if is_evening {
println!("Good evening!");// 译:"晚上好"
}
}
================================================
FILE: assets/rustlings-zh/exercises/primitive_types/primitive_types2.rs
================================================
// primitive_types2.rs
// 补充不完整代码行的缺失部分!
// 没有提示,也没有什么诀窍,只要习惯于键入这些内容就可以了 :)
// I AM NOT DONE
fn main() {
// Characters (`char`)
let my_first_initial = 'C';
if my_first_initial.is_alphabetic() {
println!("Alphabetical!");// 译:"字母!"
} else if my_first_initial.is_numeric() {
println!("Numerical!");// 译:"数字!"
} else {
println!("Neither alphabetic nor numeric!");// 译:"既不是字母也不是数字!"
}
let // 像上面的示例一样完成这行代码!你最喜欢的角色是什么?
// 试试一个字母,或者一个数字,也可以一个特殊字符,又或者一个不属于
// 你母语的字符,一个表情符号看起来也不错。
if your_character.is_alphabetic() {
println!("Alphabetical!");
} else if your_character.is_numeric() {
println!("Numerical!");
} else {
println!("Neither alphabetic nor numeric!");
}
}
================================================
FILE: assets/rustlings-zh/exercises/primitive_types/primitive_types3.rs
================================================
// primitive_types3.rs
// 在 ??? 处创建一个不少于 100 个元素的数组。
// 执行 `rustex hint primitive_types3` 获取提示!
// I AM NOT DONE
fn main() {
let a = ???
if a.len() >= 100 {
println!("Wow, that's a big array!");// 译:"哇!那数组可真大!"
} else {
println!("Meh, I eat arrays like that for breakfast.");// 译:"嗯,我把这样的数组当早餐吃。"
}
}
================================================
FILE: assets/rustlings-zh/exercises/primitive_types/primitive_types4.rs
================================================
// primitive_types4.rs
// 在 ??? 处获取数组 a 的一个切片(slice),以通过测试。
// 执行 `rustex hint primitive_types4` 获取提示!!
// I AM NOT DONE
#[test]
fn slice_out_of_array() {
let a = [1, 2, 3, 4, 5];
let nice_slice = ???
assert_eq!([2, 3, 4], nice_slice)
}
================================================
FILE: assets/rustlings-zh/exercises/primitive_types/primitive_types5.rs
================================================
// primitive_types5.rs
// 对 `cat` 元组进行解构(Destructure),使 println 能够运行。
// 执行 `rustex hint primitive_types5` 获取提示!
// I AM NOT DONE
fn main() {
let cat = ("Furry McFurson", 3.5);
let /* your pattern here */ = cat;// 译:模式写在这
println!("{} is {} years old.", name, age);
}
================================================
FILE: assets/rustlings-zh/exercises/primitive_types/primitive_types6.rs
================================================
// primitive_types6.rs
// 使用元组索引(tuple index)来访问 `numbers` 的第二个元素。
// 你可以把第二个元素的表达式放在 ??? 处,这样测试就会通过。
// 执行 `rustex hint primitive_types6` 获取提示!
// I AM NOT DONE
#[test]
fn indexing_tuple() {
let numbers = (1, 2, 3);
// 用元组索引的语法替换下面的 ???
let second = ???;
assert_eq!(2, second,
"This is not the 2nd number in the tuple!")// 译:这不是元组中的第二个数字!
}
================================================
FILE: assets/rustlings-zh/exercises/quiz1.rs
================================================
// quiz1.rs
// This is a quiz for the following sections:
// - Variables
// - Functions
// Mary is buying apples. One apple usually costs 2 Rustbucks, but if you buy
// more than 40 at once, each apple only costs 1! Write a function that calculates
// the price of an order of apples given the quantity bought. No hints this time!
// I AM NOT DONE
// Put your function here!
// fn calculate_apple_price {
// Don't modify this function!
#[test]
fn verify_test() {
let price1 = calculate_apple_price(35);
let price2 = calculate_apple_price(40);
let price3 = calculate_apple_price(65);
assert_eq!(70, price1);
assert_eq!(80, price2);
assert_eq!(65, price3);
}
================================================
FILE: assets/rustlings-zh/exercises/quiz2.rs
================================================
// quiz2.rs
// This is a quiz for the following sections:
// - Strings
// Ok, here are a bunch of values-- some are `String`s, some are `&str`s. Your
// task is to call one of these two functions on each value depending on what
// you think each value is. That is, add either `string_slice` or `string`
// before the parentheses on each line. If you're right, it will compile!
// I AM NOT DONE
fn string_slice(arg: &str) {
println!("{}", arg);
}
fn string(arg: String) {
println!("{}", arg);
}
fn main() {
???("blue");
???("red".to_string());
???(String::from("hi"));
???("rust is fun!".to_owned());
???("nice weather".into());
???(format!("Interpolation {}", "Station"));
???(&String::from("abc")[0..1]);
???(" hello there ".trim());
???("Happy Monday!".to_string().replace("Mon", "Tues"));
???("mY sHiFt KeY iS sTiCkY".to_lowercase());
}
================================================
FILE: assets/rustlings-zh/exercises/quiz3.rs
================================================
// quiz3.rs
// This is a quiz for the following sections:
// - Tests
// This quiz isn't testing our function -- make it do that in such a way that
// the test passes. Then write a second test that tests that we get the result
// we expect to get when we call `times_two` with a negative number.
// No hints, you can do this :)
// I AM NOT DONE
pub fn times_two(num: i32) -> i32 {
num * 2
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn returns_twice_of_positive_numbers() {
assert_eq!(times_two(4), ???);
}
#[test]
fn returns_twice_of_negative_numbers() {
// TODO replace unimplemented!() with an assert for `times_two(-4)`
unimplemented!()
}
}
================================================
FILE: assets/rustlings-zh/exercises/quiz4.rs
================================================
// quiz4.rs
// This quiz covers the sections:
// - Modules
// - Macros
// Write a macro that passes the quiz! No hints this time, you can do it!
// I AM NOT DONE
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_my_macro_world() {
assert_eq!(my_macro!("world!"), "Hello world!");
}
#[test]
fn test_my_macro_goodbye() {
assert_eq!(my_macro!("goodbye!"), "Hello goodbye!");
}
}
================================================
FILE: assets/rustlings-zh/exercises/standard_library_types/README.md
================================================
# Standard library types
This section will teach you about Box, Shared-State Concurrency and Iterators.
## Further information
- [Using Box to Point to Data on the Heap](https://doc.rust-lang.org/book/ch15-01-box.html)
- [Shared-State Concurrency](https://doc.rust-lang.org/book/ch16-03-shared-state.html)
- [Iterator](https://doc.rust-lang.org/book/ch13-02-iterators.html)
- [Iterator documentation](https://doc.rust-lang.org/stable/std/iter/)
================================================
FILE: assets/rustlings-zh/exercises/standard_library_types/arc1.rs
================================================
// arc1.rs
// In this exercise, we are given a Vec of u32 called "numbers" with values ranging
// from 0 to 99 -- [ 0, 1, 2, ..., 98, 99 ]
// We would like to use this set of numbers within 8 different threads simultaneously.
// Each thread is going to get the sum of every eighth value, with an offset.
// The first thread (offset 0), will sum 0, 8, 16, ...
// The second thread (offset 1), will sum 1, 9, 17, ...
// The third thread (offset 2), will sum 2, 10, 18, ...
// ...
// The eighth thread (offset 7), will sum 7, 15, 23, ...
// Because we are using threads, our values need to be thread-safe. Therefore,
// we are using Arc. We need to make a change in each of the two TODOs.
// Make this code compile by filling in a value for `shared_numbers` where the
// first TODO comment is, and create an initial binding for `child_numbers`
// where the second TODO comment is. Try not to create any copies of the `numbers` Vec!
// Execute `rustlings hint arc1` for hints :)
// I AM NOT DONE
#![forbid(unused_imports)] // Do not change this, (or the next) line.
use std::sync::Arc;
use std::thread;
fn main() {
let numbers: Vec<_> = (0..100u32).collect();
let shared_numbers = // TODO
let mut joinhandles = Vec::new();
for offset in 0..8 {
let child_numbers = // TODO
joinhandles.push(thread::spawn(move || {
let mut i = offset;
let mut sum = 0;
while i < child_numbers.len() {
sum += child_numbers[i];
i += 8;
}
println!("Sum of offset {} is {}", offset, sum);
}));
}
for handle in joinhandles.into_iter() {
handle.join().unwrap();
}
}
================================================
FILE: assets/rustlings-zh/exercises/standard_library_types/box1.rs
================================================
// box1.rs
//
// At compile time, Rust needs to know how much space a type takes up. This becomes problematic
// for recursive types, where a value can have as part of itself another value of the same type.
// To get around the issue, we can use a `Box` - a smart pointer used to store data on the heap,
// which also allows us to wrap a recursive type.
//
// The recursive type we're implementing in this exercise is the `cons list` - a data structure
// frequently found in functional programming languages. Each item in a cons list contains two
// elements: the value of the current item and the next item. The last item is a value called `Nil`.
//
// Step 1: use a `Box` in the enum definition to make the code compile
// Step 2: create both empty and non-empty cons lists by replacing `unimplemented!()`
//
// Note: the tests should not be changed
//
// Execute `rustlings hint box1` for hints :)
// I AM NOT DONE
#[derive(PartialEq, Debug)]
pub enum List {
Cons(i32, List),
Nil,
}
fn main() {
println!("This is an empty cons list: {:?}", create_empty_list());
println!(
"This is a non-empty cons list: {:?}",
create_non_empty_list()
);
}
pub fn create_empty_list() -> List {
unimplemented!()
}
pub fn create_non_empty_list() -> List {
unimplemented!()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_create_empty_list() {
assert_eq!(List::Nil, create_empty_list())
}
#[test]
fn test_create_non_empty_list() {
assert_ne!(create_empty_list(), create_non_empty_list())
}
}
================================================
FILE: assets/rustlings-zh/exercises/standard_library_types/iterators1.rs
================================================
// iterators1.rs
//
// Make me compile by filling in the `???`s
//
// When performing operations on elements within a collection, iterators are essential.
// This module helps you get familiar with the structure of using an iterator and
// how to go through elements within an iterable collection.
//
// Execute `rustlings hint iterators1` for hints :D
// I AM NOT DONE
fn main () {
let my_fav_fruits = vec!["banana", "custard apple", "avocado", "peach", "raspberry"];
let mut my_iterable_fav_fruits = ???; // TODO: Step 1
assert_eq!(my_iterable_fav_fruits.next(), Some(&"banana"));
assert_eq!(my_iterable_fav_fruits.next(), ???); // TODO: Step 2
assert_eq!(my_iterable_fav_fruits.next(), Some(&"avocado"));
assert_eq!(my_iterable_fav_fruits.next(), ???); // TODO: Step 2.1
assert_eq!(my_iterable_fav_fruits.next(), Some(&"raspberry"));
assert_eq!(my_iterable_fav_fruits.next(), ???); // TODO: Step 3
}
================================================
FILE: assets/rustlings-zh/exercises/standard_library_types/iterators2.rs
================================================
// iterators2.rs
// In this exercise, you'll learn some of the unique advantages that iterators
// can offer. Follow the steps to complete the exercise.
// As always, there are hints if you execute `rustlings hint iterators2`!
// I AM NOT DONE
// Step 1.
// Complete the `capitalize_first` function.
// "hello" -> "Hello"
pub fn capitalize_first(input: &str) -> String {
let mut c = input.chars();
match c.next() {
None => String::new(),
Some(first) => ???,
}
}
// Step 2.
// Apply the `capitalize_first` function to a slice of string slices.
// Return a vector of strings.
// ["hello", "world"] -> ["Hello", "World"]
pub fn capitalize_words_vector(words: &[&str]) -> Vec<String> {
vec![]
}
// Step 3.
// Apply the `capitalize_first` function again to a slice of string slices.
// Return a single string.
// ["hello", " ", "world"] -> "Hello World"
pub fn capitalize_words_string(words: &[&str]) -> String {
String::new()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_success() {
assert_eq!(capitalize_first("hello"), "Hello");
}
#[test]
fn test_empty() {
assert_eq!(capitalize_first(""), "");
}
#[test]
fn test_iterate_string_vec() {
let words = vec!["hello", "world"];
assert_eq!(capitalize_words_vector(&words), ["Hello", "World"]);
}
#[test]
fn test_iterate_into_string() {
let words = vec!["hello", " ", "world"];
assert_eq!(capitalize_words_string(&words), "Hello World");
}
}
================================================
FILE: assets/rustlings-zh/exercises/standard_library_types/iterators3.rs
================================================
// iterators3.rs
// This is a bigger exercise than most of the others! You can do it!
// Here is your mission, should you choose to accept it:
// 1. Complete the divide function to get the first four tests to pass.
// 2. Get the remaining tests to pass by completing the result_with_list and
// list_of_results functions.
// Execute `rustlings hint iterators3` to get some hints!
// I AM NOT DONE
#[derive(Debug, PartialEq, Eq)]
pub enum DivisionError {
NotDivisible(NotDivisibleError),
DivideByZero,
}
#[derive(Debug, PartialEq, Eq)]
pub struct NotDivisibleError {
dividend: i32,
divisor: i32,
}
// Calculate `a` divided by `b` if `a` is evenly divisible by `b`.
// Otherwise, return a suitable error.
pub fn divide(a: i32, b: i32) -> Result<i32, DivisionError> {}
// Complete the function and return a value of the correct type so the test passes.
// Desired output: Ok([1, 11, 1426, 3])
fn result_with_list() -> () {
let numbers = vec![27, 297, 38502, 81];
let division_results = numbers.into_iter().map(|n| divide(n, 27));
}
// Complete the function and return a value of the correct type so the test passes.
// Desired output: [Ok(1), Ok(11), Ok(1426), Ok(3)]
fn list_of_results() -> () {
let numbers = vec![27, 297, 38502, 81];
let division_results = numbers.into_iter().map(|n| divide(n, 27));
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_success() {
assert_eq!(divide(81, 9), Ok(9));
}
#[test]
fn test_not_divisible() {
assert_eq!(
divide(81, 6),
Err(DivisionError::NotDivisible(NotDivisibleError {
dividend: 81,
divisor: 6
}))
);
}
#[test]
fn test_divide_by_0() {
assert_eq!(divide(81, 0), Err(DivisionError::DivideByZero));
}
#[test]
fn test_divide_0_by_something() {
assert_eq!(divide(0, 81), Ok(0));
}
#[test]
fn test_result_with_list() {
assert_eq!(format!("{:?}", result_with_list()), "Ok([1, 11, 1426, 3])");
}
#[test]
fn test_list_of_results() {
assert_eq!(
format!("{:?}", list_of_results()),
"[Ok(1), Ok(11), Ok(1426), Ok(3)]"
);
}
}
================================================
FILE: assets/rustlings-zh/exercises/standard_library_types/iterators4.rs
================================================
// iterators4.rs
// I AM NOT DONE
pub fn factorial(num: u64) -> u64 {
// Complete this function to return the factorial of num
// Do not use:
// - return
// Try not to use:
// - imperative style loops (for, while)
// - additional variables
// For an extra challenge, don't use:
// - recursion
// Execute `rustlings hint iterators4` for hints.
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn factorial_of_1() {
assert_eq!(1, factorial(1));
}
#[test]
fn factorial_of_2() {
assert_eq!(2, factorial(2));
}
#[test]
fn factorial_of_4() {
assert_eq!(24, factorial(4));
}
}
================================================
FILE: assets/rustlings-zh/exercises/standard_library_types/iterators5.rs
================================================
// iterators5.rs
// Let's define a simple model to track Rustlings exercise progress. Progress
// will be modelled using a hash map. The name of the exercise is the key and
// the progress is the value. Two counting functions were created to count the
// number of exercises with a given progress. These counting functions use
// imperative style for loops. Recreate this counting functionality using
// iterators. Only the two iterator methods (count_iterator and
// count_collection_iterator) need to be modified.
// Execute `rustlings hint iterators5` for hints.
//
// Make the code compile and the tests pass.
// I AM NOT DONE
use std::collections::HashMap;
#[derive(Clone, Copy, PartialEq, Eq)]
enum Progress {
None,
Some,
Complete,
}
fn count_for(map: &HashMap<String, Progress>, value: Progress) -> usize {
let mut count = 0;
for val in map.values() {
if val == &value {
count += 1;
}
}
count
}
fn count_iterator(map: &HashMap<String, Progress>, value: Progress) -> usize {
// map is a hashmap with String keys and Progress values.
// map = { "variables1": Complete, "from_str": None, ... }
}
fn count_collection_for(collection: &[HashMap<String, Progress>], value: Progress) -> usize {
let mut count = 0;
for map in collection {
for val in map.values() {
if val == &value {
count += 1;
}
}
}
count
}
fn count_collection_iterator(collection: &[HashMap<String, Progress>], value: Progress) -> usize {
// collection is a slice of hashmaps.
// collection = [{ "variables1": Complete, "from_str": None, ... },
// { "variables2": Complete, ... }, ... ]
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn count_complete() {
let map = get_map();
assert_eq!(3, count_iterator(&map, Progress::Complete));
}
#[test]
fn count_equals_for() {
let map = get_map();
assert_eq!(
count_for(&map, Progress::Complete),
count_iterator(&map, Progress::Complete)
);
}
#[test]
fn count_collection_complete() {
let collection = get_vec_map();
assert_eq!(
6,
count_collection_iterator(&collection, Progress::Complete)
);
}
#[test]
fn count_collection_equals_for() {
let collection = get_vec_map();
assert_eq!(
count_collection_for(&collection, Progress::Complete),
count_collection_iterator(&collection, Progress::Complete)
);
}
fn get_map() -> HashMap<String, Progress> {
use Progress::*;
let mut map = HashMap::new();
map.insert(String::from("variables1"), Complete);
map.insert(String::from("functions1"), Complete);
map.insert(String::from("hashmap1"), Complete);
map.insert(String::from("arc1"), Some);
map.insert(String::from("as_ref_mut"), None);
map.insert(String::from("from_str"), None);
map
}
fn get_vec_map() -> Vec<HashMap<String, Progress>> {
use Progress::*;
let map = get_map();
let mut other = HashMap::new();
other.insert(String::from("variables2"), Complete);
other.insert(String::from("functions2"), Complete);
other.insert(String::from("if1"), Complete);
other.insert(String::from("from_into"), None);
other.insert(String::from("try_from_into"), None);
vec![map, other]
}
}
================================================
FILE: assets/rustlings-zh/exercises/strings/README.md
================================================
# 字符串
Rust 有两种字符串类型,一种是字符串切片(`&str`),另一种是拥有所有权的字符串(`String`)。我们不打算向你说明何时使用其中哪一种,但我们将为你讲解如何区分和创建它们,并灵活使用。
## 更多信息
- [Strings](https://doc.rust-lang.org/book/ch08-02-strings.html)
================================================
FILE: assets/rustlings-zh/exercises/strings/strings1.rs
================================================
// strings1.rs
// 在不改变函数签名的要求下通过编译!
// 执行 `rustlings hint strings1` 获取提示 ;)
// I AM NOT DONE
fn main() {
let answer = current_favorite_color();
println!("My current favorite color is {}", answer);// 译:"当前我最喜爱的颜色是 {}"
}
// 译:当前最喜爱的颜色
fn current_favorite_color() -> String {
"blue"
}
================================================
FILE: assets/rustlings-zh/exercises/strings/strings2.rs
================================================
// strings2.rs
// 在不改变函数签名的要求下通过编译!
// 执行 `rustlings hint strings2` 获取提示 ;)
// I AM NOT DONE
fn main() {
let word = String::from("green"); // 尝试不更改这一行 :)
if is_a_color_word(word) {
println!("That is a color word I know!");// 译:我知道这个颜色词
} else {
println!("That is not a color word I know.");// 译:我不知道这个颜色词
}
}
// 译:是否是颜色词
fn is_a_color_word(attempt: &str) -> bool {
attempt == "green" || attempt == "blue" || attempt == "red"
}
================================================
FILE: assets/rustlings-zh/exercises/structs/README.md
================================================
# 结构(Structs)
Rust 有三种结构类型:经典的 C 结构、元组结构和单元结构。
## 更多信息
- [Structures](https://doc.rust-lang.org/book/ch05-01-defining-structs.html)
- [Method Syntax](https://doc.rust-lang.org/book/ch05-03-method-syntax.html)
================================================
FILE: assets/rustlings-zh/exercises/structs/structs1.rs
================================================
// structs1.rs
// 解决所有的 TODO ,通过测试!
// I AM NOT DONE
struct ColorClassicStruct {
// TODO: 一些东西需要在这里
}
struct ColorTupleStruct(/* TODO: 一些东西需要在这里 */);
#[derive(Debug)]
struct UnitStruct;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn classic_c_structs() {
// TODO: 实例化一个经典的 C 结构体!
// let green =
assert_eq!(green.name, "green");
assert_eq!(green.hex, "#00FF00");
}
#[test]
fn tuple_structs() {
// TODO: 实例化一个元组结构!
// let green =
assert_eq!(green.0, "green");
assert_eq!(green.1, "#00FF00");
}
#[test]
fn unit_structs() {
// TODO: 实例化一个单元结构!
// let unit_struct =
let message = format!("{:?}s are fun!", unit_struct);
assert_eq!(message, "UnitStructs are fun!");
}
}
================================================
FILE: assets/rustlings-zh/exercises/structs/structs2.rs
================================================
// structs2.rs
// 解决所有的 TODO ,通过测试!
// I AM NOT DONE
#[derive(Debug)]
struct Order {
name: String,
year: u32,
made_by_phone: bool,
made_by_mobile: bool,
made_by_email: bool,
item_number: u32,
count: u32,
}
fn create_order_template() -> Order {
Order {
name: String::from("Bob"),
year: 2019,
made_by_phone: false,
made_by_mobile: false,
made_by_email: true,
item_number: 123,
count: 0,
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn your_order() {
let order_template = create_order_template();
// TODO: 利用上面的模板(template 是模板的意思)然后改变其中的一些值来创建属于你的订单!
// let your_order =
assert_eq!(your_order.name, "Hacker in Rust");
assert_eq!(your_order.year, order_template.year);
assert_eq!(your_order.made_by_phone, order_template.made_by_phone);
assert_eq!(your_order.made_by_mobile, order_template.made_by_mobile);
assert_eq!(your_order.made_by_email, order_template.made_by_email);
assert_eq!(your_order.item_number, order_template.item_number);
assert_eq!(your_order.count, 1);
}
}
================================================
FILE: assets/rustlings-zh/exercises/structs/structs3.rs
================================================
// structs3.rs
// 接口既可以包含数据也可以处理逻辑。
// 在这个练习中,我们已经定义了 Package 结构,但我们想测试一些根据它实现的逻辑。
// 让代码通过编译和测试!
// 如果你有问题,可以执行 `rustlings hint structs3` 查看提示
// I AM NOT DONE
#[derive(Debug)]
struct Package {// 译:包裹
sender_country: String,// 译:寄件人国家
recipient_country: String,// 译:收件人国家
weight_in_grams: i32,// 译:重量(克)
}
impl Package {
fn new(sender_country: String, recipient_country: String, weight_in_grams: i32) -> Package {
if weight_in_grams <= 0 {
// 这里需要完成一些东西……
} else {
Package {
sender_country,
recipient_country,
weight_in_grams,
}
}
}
fn is_international(&self) -> ??? {// 译:是否是国际上的
// 这里需要完成一些东西……
}
fn get_fees(&self, cents_per_gram: i32) -> ??? {// 译:获取所需费用
// 这里需要完成一些东西……
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
#[should_panic]
fn fail_creating_weightless_package() {// 译:失败地创建没有重量的包裹
let sender_country = String::from("Spain");// 译:西班牙
let recipient_country = String::from("Austria");// 译:奥地利
Package::new(sender_country, recipient_country, -2210);
}
#[test]
fn create_international_package() {// 译:创建国际上的包裹
let sender_country = String::from("Spain");
let recipient_country = String::from("Russia");
let package = Package::new(sender_country, recipient_country, 1200);
assert!(package.is_international());
}
#[test]
fn create_local_package() {
let sender_country = String::from("Canada");
let recipient_country = sender_country.clone();
let package = Package::new(sender_country, recipient_country, 1200);
assert!(!package.is_international());
}
#[test]
fn calculate_transport_fees() {// 译:计算运输费
let sender_country = String::from("Spain");
let recipient_country = String::from("Spain");
let cents_per_gram = 3;// 译:分/克(一克需要多少分钱)
let package = Package::new(sender_country, recipient_country, 1500);
assert_eq!(package.get_fees(cents_per_gram), 4500);
}
}
================================================
FILE: assets/rustlings-zh/exercises/tests/README.md
================================================
# 测试
这次不按书本上的顺序介绍测试——接下来的很多练习都会要求你通过测试!
## 更多信息
- [Writing Tests](https://doc.rust-lang.org/book/ch11-01-writing-tests.html)
================================================
FILE: assets/rustlings-zh/exercises/tests/tests1.rs
================================================
// tests1.rs
// 测试对于确保代码实现了预期功能非常重要。
// 可以用下面的命令对当前文件中的代码进行测试:
// rustlings run tests1
// 关于测试还有个问题——如何成功编译测试、通过测试或者使测试失败?
// 执行 `rustlings hint tests1` 获取提示 :)
// I AM NOT DONE
#[cfg(test)]
mod tests {
#[test]
fn you_can_assert() {
assert!();
}
}
================================================
FILE: assets/rustlings-zh/exercises/tests/tests2.rs
================================================
// tests2.rs
// 让测试能够编译然后通过测试和使测试失败!
// 执行 `rustlings hint tests2` 获取提示 :)
// I AM NOT DONE
#[cfg(test)]
mod tests {
#[test]
fn you_can_assert_eq() {
assert_eq!();
}
}
================================================
FILE: assets/rustlings-zh/exercises/tests/tests3.rs
================================================
// tests3.rs
// 这个测试不是在测试我们的函数——想些方法让它的返回值可以通过测试。
// 在第二个测试判断调用 `is_even(5)` 是否得到了预期的结果。
// 执行 `rustlings hint tests3` 获取提示 :)
// I AM NOT DONE
pub fn is_even(num: i32) -> bool {
num % 2 == 0
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn is_true_when_even() {// 偶数将返回 true
assert!();
}
#[test]
fn is_false_when_odd() {// 奇数将返回 false
assert!();
}
}
================================================
FILE: assets/rustlings-zh/exercises/threads/README.md
================================================
# Threads
In most current operating systems, an executed program’s code is run in a process, and the operating system manages multiple processes at once.
Within your program, you can also have independent parts that run simultaneously. The features that run these independent parts are called threads.
## Further information
- [Dining Philosophers example](https://doc.rust-lang.org/1.4.0/book/dining-philosophers.html)
- [Using Threads to Run Code Simultaneously](https://doc.rust-lang.org/book/ch16-01-threads.html)
================================================
FILE: assets/rustlings-zh/exercises/threads/threads1.rs
================================================
// threads1.rs
// Make this compile! Execute `rustlings hint threads1` for hints :)
// The idea is the thread spawned on line 22 is completing jobs while the main thread is
// monitoring progress until 10 jobs are completed. Because of the difference between the
// spawned threads' sleep time, and the waiting threads sleep time, when you see 6 lines
// of "waiting..." and the program ends without timing out when running,
// you've got it :)
// I AM NOT DONE
use std::sync::Arc;
use std::thread;
use std::time::Duration;
struct JobStatus {
jobs_completed: u32,
}
fn main() {
let status = Arc::new(JobStatus { jobs_completed: 0 });
let status_shared = status.clone();
thread::spawn(move || {
for _ in 0..10 {
thread::sleep(Duration::from_millis(250));
status_shared.jobs_completed += 1;
}
});
while status.jobs_completed < 10 {
println!("waiting... ");
thread::sleep(Duration::from_millis(500));
}
}
================================================
FILE: assets/rustlings-zh/exercises/traits/README.md
================================================
# Traits
Trait 是一系列方法的集合。
数据类型可以实现 trait。为此需要帮数据类型定义好构成 trait 的方法。
例如,`String` 类型实现了 `From<&str>` trait。它赋予我们能力写出 `String::from("hello")`。
如此一来,trait 就有点类似于 Java 的接口和 C++ 的抽象类。
另外一些常见的 Rust trait 包括:
- `Clone` (`clone` 方法)
- `Display` (实现通过 `{}` 进行格式化显示)
- `Debug` (实现通过 `{:?}` 进行格式化显示 )
因为 trait 标明了数据类型之间的共有行为,所以它在编写泛型时非常有用。
## 更多信息
- [Traits](https://doc.rust-lang.org/book/ch10-02-traits.html)
================================================
FILE: assets/rustlings-zh/exercises/traits/traits1.rs
================================================
// traits1.rs
// 是时候来实现些 trait 了!
//
// 你的任务是为 `String` 实现 `AppendBar` trait。
//
// `AppendBar` 只有一个函数,它将 "Bar" 追加到任何实现该 trait 的对象上。
// 译:Append 有追加、附加的意思,所以“追加/附加 Bar”。
// I AM NOT DONE
trait AppendBar {
fn append_bar(self) -> Self;
}
impl AppendBar for String {
// 在这里编写代码
}
fn main() {
let s = String::from("Foo");
let s = s.append_bar();
println!("s: {}", s);
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn is_foo_bar() {
assert_eq!(String::from("Foo").append_bar(), String::from("FooBar"));
}
#[test]
fn is_bar_bar() {
assert_eq!(
String::from("").append_bar().append_bar(),
String::from("BarBar")
);
}
}
================================================
FILE: assets/rustlings-zh/exercises/traits/traits2.rs
================================================
// traits2.rs
//
// 你的任务是为一个字符串 vector 实现 `AppendBar` trait。
//
// 为了实现该 trait,请思考下将 "Bar" 追加到字符串 vector 的意义是什么?
//
// 这次没有样板代码,相信自己!
// I AM NOT DONE
trait AppendBar {
fn append_bar(self) -> Self;
}
//TODO:在这编写代码
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn is_vec_pop_eq_bar() {
let mut foo = vec![String::from("Foo")].append_bar();
assert_eq!(foo.pop().unwrap(), String::from("Bar"));
assert_eq!(foo.pop().unwrap(), String::from("Foo"));
}
}
================================================
FILE: assets/rustlings-zh/exercises/variables/README.md
================================================
# 变量(Variables)
在 Rust,变量默认是不可变的.
不可变意味着当一个值被绑定到某个名字上,你就不能再对这个值做出更改。
当然,你可以通过在变量名前添加 mut 来使它们变得可变。
## 更多信息
- [Variables and Mutability](https://doc.rust-lang.org/book/ch03-01-variables-and-mutability.html)
================================================
FILE: assets/rustlings-zh/exercises/variables/variables1.rs
================================================
// variables1.rs
// 让我能够编译!执行 `rustex hint variables1` 获取提示 :)
// 关于 `I AM NOT DONE`:
// 即使你已经想到了解决方案,我们有时也会鼓励你在特定的练习
// 继续去尝试做到更好。如果你已经通过练习并做好了应对下一题
// 的准备, 请删除下面的 `I AM NOT DONE` 注释。
// I AM NOT DONE
/// 翻译: [mg-chao](https://github.com/mg-chao)
/// 加油 💪
fn main() {
x = 5;
println!("x has the value {}", x);// 译:x 的值是
}
================================================
FILE: assets/rustlings-zh/exercises/variables/variables2.rs
================================================
// variables2.rs
// 让我能够编译!执行 `rustex hint variables2` 获取提示 :)
// I AM NOT DONE
/// 翻译: [mg-chao](https://github.com/mg-chao)
fn main() {
let x;
if x == 10 {
println!("Ten!");// 译:十!
} else {
println!("Not ten!");// 译:不是十!
}
}
================================================
FILE: assets/rustlings-zh/exercises/variables/variables3.rs
================================================
// variables3.rs
// 让我能够编译!执行 `rustex hint variables3` 获取提示 :)
// I AM NOT DONE
/// 翻译: [mg-chao](https://github.com/mg-chao)
fn main() {
let x = 3;
println!("Number {}", x);// 译:"数字 {}"
x = 5; // don't change this line(译:不要更改这一行)
println!("Number {}", x);
}
================================================
FILE: assets/rustlings-zh/exercises/variables/variables4.rs
================================================
// variables4.rs
// 让我能够编译!执行 `rustex hint variables4` 获取提示 :)
// I AM NOT DONE
/// 翻译: [mg-chao](https://github.com/mg-chao)
fn main() {
let x: i32;
println!("Number {}", x);
}
================================================
FILE: assets/rustlings-zh/exercises/variables/variables5.rs
================================================
// variables5.rs
// 让我能够编译!执行 `rustex hint variables5` 获取提示 :)
// I AM NOT DONE
/// 翻译: [mg-chao](https://github.com/mg-chao)
fn main() {
let number = "T-H-R-E-E"; // don't change this line
println!("Spell a Number : {}", number);// 译:"拼接的数字:{}"
number = 3;
println!("Number plus two is : {}", number + 2);// 译:"数字加上二是:{}"
}
================================================
FILE: assets/rustlings-zh/exercises/variables/variables6.rs
================================================
// variables6.rs
// 让我能够编译!执行 `rustex hint variables6` 获取提示 :)
// I AM NOT DONE
/// 翻译: [mg-chao](https://github.com/mg-chao)
const NUMBER = 3;
fn main() {
println!("Number {}", NUMBER);
}
================================================
FILE: assets/rustlings-zh/info.toml
================================================
# VARIABLES
[[exercises]]
name = "variables1"
path = "exercises/variables/variables1.rs"
mode = "compile"
hint = """
提示: 第 12 行的变量声明缺少了一个关键字,在 Rust 中,创建一个
新的变量绑定必须用到这个关键字。"""
[[exercises]]
name = "variables2"
path = "exercises/variables/variables2.rs"
mode = "compile"
hint = """
编译器在说,Rust 无法根据给定内容推断出变量 `x` 的类型.
如果你对第 7 行标注类型,会发生什么?
如果你对 x 赋予一个值呢?
如果你同时做到了以上两点呢?
x 到底是什么类型?
如果 x 与 10 是同一类型,亦或者它是不同的类型呢?"""
[[exercises]]
name = "variables3"
path = "exercises/variables/variables3.rs"
mode = "compile"
hint = """
在 Rust,变量绑定默认是不可变的。但我们正试图重新分配
一个不同的值给 x !我们可以使用一个关键字使变量可变。"""
[[exercises]]
name = "variables4"
path = "exercises/variables/variables4.rs"
mode = "compile"
hint = """
糟了!在这个练习中,我们在第 7 行创建了一个变量,然后试图在第 8 行
使用它,但是它并没被赋值!我们无法打印出不存在的内容,所以尝试赋予 x 一个值!
这个错误造成的 Bug 在任何编程语言中都非常容易发生——感谢 Rust 编译器提醒了我们"""
[[exercises]]
name = "variables5"
path = "exercises/variables/variables5.rs"
mode = "compile"
hint = """
在 variables3 中,我们已经学会了使用一个特殊的关键字使一个不可变的变量变得可变。
可惜的是,在这个练习中,这个方法并不管用,因为我们想给一个现有的变量分配一个不
同类型的值。有时,你会想重复使用现有的变量名称,因为你只是将数值转换为不同的类型,就像
本练习中一样。幸运的是,Rust 有一个强大的技术可以解决这个问题:变量遮蔽(Shadowing)!
有关变量遮蔽的更多内容可通过这本书的 'Variables and Mutability'* 章节了解:
https://doc.rust-lang.org/book/ch03-01-variables-and-mutability.html#shadowing
尝试使用此技术解决此练习。
译:Variables and Mutability:变量与可变性"""
[[exercises]]
name = "variables6"
path = "exercises/variables/variables6.rs"
mode = "compile"
hint = """
我们已经了解了变量与可变性,但还有另一种重要的变量类型;常量(Constant)。
常量永远不可改变的,它用关键字 'const' 而非关键字 'let' 声明,并且其类型也必须被标注。
更多关于常量的信息 'Differences Between Variables and Constants'* 在这本书的章节 'Variables and Mutability':
https://doc.rust-lang.org/book/ch03-01-variables-and-mutability.html#differences-between-variables-and-constants
译:Differences Between Variables and Constants:变量与常量的区别
"""
# FUNCTIONS
[[exercises]]
name = "functions1"
path = "exercises/functions/functions1.rs"
mode = "compile"
hint = """
主函数中正试图调用一个名为 `call_me` 的函数,可这个函数并不存在。
它希望这个函数不接受任何参数,同时也不返回值。
听起来很像 `main` 函数,不是吗?"""
[[exercises]]
name = "functions2"
path = "exercises/functions/functions2.rs"
mode = "compile"
hint = """
Rust 要求函数签名(signature)有类型标注,但是 `call_me` 函数缺少 `num` 的类型标注。"""
[[exercises]]
name = "functions3"
path = "exercises/functions/functions3.rs"
mode = "compile"
hint = """
此时, 函数 *声明(declaration)* 是没问题的,但函数调用出了问题"""
[[exercises]]
name = "functions4"
path = "exercises/functions/functions4.rs"
mode = "compile"
hint = """
错误信息指向第 15 行,说希望在`->`之后有一个类型。
那个地方标注了函数的返回类型——看看 `is_even` 函数的示例吧"""
[[exercises]]
name = "functions5"
path = "exercises/functions/functions5.rs"
mode = "compile"
hint = """
这是一个非常常见的错误,可以通过删除一个字符来解决。
发生的原因是 Rust 区分了表达式和语句:表达式根据其运算数(operand)返回一个值,
而语句仅返回一个 `()` 类型,其行为好比 C/C++ 中的 `void` 。
我们希望 `square` 函数返回一个 `i32` 类型的值,但现在它返回的是 `()` 类型...
它们显然是不一样的。对此有两种解决方案。
1. 在 `num * num;` 前面加上 `return` 关键字
2. 移除 `;`,让它变成 `num * num`"""
# IF
[[exercises]]
name = "if1"
path = "exercises/if/if1.rs"
mode = "test"
hint = """
如果你愿意的话,也可以用一行来做这件事!
其他语言中的一些类似例子:
- 在 C(++) 中会是: `a > b ? a : b`
- 在 Python 中会是: `a if a > b else b`
请记住在 Rust 中:
- `if` 的条件不需要用圆括号括起来
- `if`/`else` 的条件是表达式
- 每个条件后面都有一个 `{}` 块。"""
[[exercises]]
name = "if2"
path = "exercises/if/if2.rs"
mode = "test"
hint = """
对于第一个编译错误,在于 Rust 中的重要一点:
每个条件块(conditional block)都必须返回相同的类型。
为了通过测试,你需要几个条件用来判断不同的输入"""
# TEST 1
[[exercises]]
name = "quiz1"
path = "exercises/quiz1.rs"
mode = "test"
hint = "No hints this time ;)"
# MOVE SEMANTICS
[[exercises]]
name = "move_semantics1"
path = "exercises/move_semantics/move_semantics1.rs"
mode = "compile"
hint = """
在第 13 行有个 "cannot borrow immutable local variable `vec1` as mutable"* 错误,对吗?
修复错误的方法是添加一个关键词,并且添加的位置不在报错的第 13 行上。
译注:不能将不可变的局部变量 `vec1` 借用为可变变量"""
[[exercises]]
name = "move_semantics2"
path = "exercises/move_semantics/move_semantics2.rs"
mode = "compile"
hint = """
当我们在第 10 行调用 `fill_vec` 时,`vec0' 被 *移动(moved)* 到
函数 `fill_vec` 中,这意味着它会在 `fill_vec` 函数的末尾被丢弃,同时也
导致了我们不能在第 13 行再次使用 `vec0`(或在 `main` 中调用 `fill_vec` 后的任何地方)。
我们可以用几种方法来解决这个问题,都试一试吧!
1. 做一个 `vec0` 数据的拷贝,并将其传递给 `fill_vec` 。
2. 让 `fill_vec` 通过借用而不是获取所有权的方式获取参数,然后在函数中复制一份数据,以便返回
一个具有所有权的 `Vec<i32>` 变量。
3. 让 `fill_vec` 借用可变参数(参数也需要可变),直接进行操作,然后不返回任何东西。接着你需要
完全地去掉 `vec1`——但注意,这也将改变第一个 `println!` 打印出内容。"""
[[exercises]]
name = "move_semantics3"
path = "exercises/move_semantics/move_semantics3.rs"
mode = "compile"
hint = """
与之前不同:`fn fill_vec` 第一行的 `let mut vec = vec;` 现在已经不存在了。
你可以在某个地方添加 `mut` 以使现有的不可变绑定变得可变,而非把不同的那一行加回去 :)"""
[[exercises]]
name = "move_semantics4"
path = "exercises/move_semantics/move_semantics4.rs"
mode = "compile"
hint = """
只要你觉得有确切的目标,就可以停止阅读 :) 或者试着做一个步骤,然后修复编译错误。
因此,目标有:
- 去掉 main 中创建新 vector 的第一行
- 所以 `vec0` 已不存在了,不能再把它传给 `fill_vec` 。
- 现已不需要向 `fill_vec` 传递任何东西,所以它的(函数)签名应该反映出它不接受任何参数*。
- 由于已不在 `main` 创建 vector ,所以需要在 `fill_vec` 中创建一个新的 vector,
类似于 `main` 中的做法。
译注:练习中 fill_vec 的函数签名已经没有接受参数了,所以估计是在调用的地方"""
[[exercises]]
name = "move_semantics5"
path = "exercises/move_semantics/move_semantics5.rs"
mode = "compile"
hint = """
仔细推敲每个可变引用的使用范围。
在获取可变引用后是否能够立即更新引用(x)的值?
在本书的 'References and Borrowing' 部分了解更多关于 'Mutable References' 的信息。
https://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html#mutable-references.
"""
# PRIMITIVE TYPES
[[exercises]]
name = "primitive_types1"
path = "exercises/primitive_types/primitive_types1.rs"
mode = "compile"
hint = "这次没有提示 ;)"
[[exercises]]
name = "primitive_types2"
path = "exercises/primitive_types/primitive_types2.rs"
mode = "compile"
hint = "这次没有提示 ;)"
[[exercises]]
name = "primitive_types3"
path = "exercises/primitive_types/primitive_types3.rs"
mode = "compile"
hint = """
有一种简便的方法可以初始化具有一定大小的数组,而不需要你输入 100 个
元素(但如果你想的话,那当然可以!)。
例如,你可以这样做:
let array = ["Are we there yet?"; 10];
额外目标: 还有哪些东西可以在 `a.len()>=100` 时返回 true """
[[exercises]]
name = "primitive_types4"
path = "exercises/primitive_types/primitive_types4.rs"
mode = "test"
hint = """
看看这本书的:Understanding Ownership -> Slices -> Other Slices 章节吧:
https://doc.rust-lang.org/book/ch04-03-slices.html,
然后找出所需切片元素对应数组里的起始和截止下标。
如果你好奇既然 `assert_eq!` 的第二个参数是引用,为什么第一个参数
没有使用 & 号用来表示引用,可以看看这本书的 Deref 强制转换部分:
https://doc.rust-lang.org/book/ch15-02-deref.html"""
[[exercises]]
name = "primitive_types5"
path = "exercises/primitive_types/primitive_types5.rs"
mode = "compile"
hint = """
看看这本书的 Data Types -> The Tuple Type 类型章节:
https://doc.rust-lang.org/book/ch03-02-data-types.html#the-tuple-type
特别是关于解构的部分(这节中倒数第二个例子)。
你需要一个模式将 `name` 和 `age` 绑定到元组的适当部分。你能够做到的!!"""
[[exercises]]
name = "primitive_types6"
path = "exercises/primitive_types/primitive_types6.rs"
mode = "test"
hint = """
虽然你可以使用 `let` 对元组进行解构 ,但不妨试试对它进行索引,
正如这本书的 Data Types -> The Tuple Type 部分的最后一个例子表示的那样。
https://doc.rust-lang.org/book/ch03-02-data-types.html#the-tuple-type
现在,你的工具箱里又多了一个工具!"""
# STRUCTS
[[exercises]]
name = "structs1"
path = "exercises/structs/structs1.rs"
mode = "test"
hint = """
Rust 不只有一种结构。实际上,所有的变体都是用来组合相关的数据。
首先是一般的(或经典的)结构,一块相关的数据被命名为一个字段集合。
元组结构基本上就是被命名的元组。
最后的单元结构没有任何字段,对泛型很有用。
在这个练习中,你需要完成并实现每一种结构。
更多关于结构的内容在这:https://doc.rust-lang.org/book/ch05-01-defining-structs.html"""
[[exercises]]
name = "structs2"
path = "exercises/structs/structs2.rs"
mode = "test"
hint = """
创建结构体的实例很简单,你只需要给它的字段分配一些值。
然而,在实例化结构时,还有些捷径。
看看这本书,来了解更多:https://doc.rust-lang.org/stable/book/ch05-01-defining-structs.html#creating-instances-from-other-instances-with-struct-update-syntax"""
[[exercises]]
name = "structs3"
path = "exercises/structs/structs3.rs"
mode = "test"
hint = """
Package 实现的 new 方法在重量(weight_in_grams)不符合物理的情况下需要 panic :),这在 Rust 需要怎么做?
对于 is_international:一个包裹具有国际性的条件有哪些?似乎与它所经过的地方有关吧?
对于 calculate_transport_fees:更大的通常更贵,我们的 Package 没有尺寸,但有些东西可能同样符合需要 :)
看看这本书,了解更多关于方法实现的信息:https://doc.rust-lang.org/book/ch05-03-method-synt
gitextract_g9fgxovm/
├── .github/
│ └── workflows/
│ ├── ci.yml
│ └── deploy.yml
├── .gitignore
├── README.md
├── assets/
│ ├── CNAME
│ ├── bigPicture.js
│ ├── custom.js
│ ├── rustlings-zh/
│ │ ├── .all-contributorsrc
│ │ ├── .clog.toml
│ │ ├── .editorconfig
│ │ ├── .gitignore
│ │ ├── .gitpod.yml
│ │ ├── .replit
│ │ ├── CHANGELOG.md
│ │ ├── CONTRIBUTING.md
│ │ ├── Cargo.toml
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── default_out.txt
│ │ ├── exercises/
│ │ │ ├── README.md
│ │ │ ├── advanced_errors/
│ │ │ │ ├── advanced_errs1.rs
│ │ │ │ └── advanced_errs2.rs
│ │ │ ├── clippy/
│ │ │ │ ├── README.md
│ │ │ │ ├── clippy1.rs
│ │ │ │ └── clippy2.rs
│ │ │ ├── collections/
│ │ │ │ ├── README.md
│ │ │ │ ├── hashmap1.rs
│ │ │ │ ├── hashmap2.rs
│ │ │ │ ├── vec1.rs
│ │ │ │ └── vec2.rs
│ │ │ ├── conversions/
│ │ │ │ ├── README.md
│ │ │ │ ├── as_ref_mut.rs
│ │ │ │ ├── from_into.rs
│ │ │ │ ├── from_str.rs
│ │ │ │ ├── try_from_into.rs
│ │ │ │ └── using_as.rs
│ │ │ ├── enums/
│ │ │ │ ├── README.md
│ │ │ │ ├── enums1.rs
│ │ │ │ ├── enums2.rs
│ │ │ │ └── enums3.rs
│ │ │ ├── error_handling/
│ │ │ │ ├── README.md
│ │ │ │ ├── errors1.rs
│ │ │ │ ├── errors2.rs
│ │ │ │ ├── errors3.rs
│ │ │ │ ├── errors4.rs
│ │ │ │ ├── errors5.rs
│ │ │ │ └── errors6.rs
│ │ │ ├── functions/
│ │ │ │ ├── README.md
│ │ │ │ ├── functions1.rs
│ │ │ │ ├── functions2.rs
│ │ │ │ ├── functions3.rs
│ │ │ │ ├── functions4.rs
│ │ │ │ └── functions5.rs
│ │ │ ├── generics/
│ │ │ │ ├── README.md
│ │ │ │ ├── generics1.rs
│ │ │ │ ├── generics2.rs
│ │ │ │ └── generics3.rs
│ │ │ ├── if/
│ │ │ │ ├── README.md
│ │ │ │ ├── if1.rs
│ │ │ │ └── if2.rs
│ │ │ ├── macros/
│ │ │ │ ├── README.md
│ │ │ │ ├── macros1.rs
│ │ │ │ ├── macros2.rs
│ │ │ │ ├── macros3.rs
│ │ │ │ └── macros4.rs
│ │ │ ├── modules/
│ │ │ │ ├── README.md
│ │ │ │ ├── modules1.rs
│ │ │ │ ├── modules2.rs
│ │ │ │ └── modules3.rs
│ │ │ ├── move_semantics/
│ │ │ │ ├── README.md
│ │ │ │ ├── move_semantics1.rs
│ │ │ │ ├── move_semantics2.rs
│ │ │ │ ├── move_semantics3.rs
│ │ │ │ ├── move_semantics4.rs
│ │ │ │ └── move_semantics5.rs
│ │ │ ├── option/
│ │ │ │ ├── README.md
│ │ │ │ ├── option1.rs
│ │ │ │ ├── option2.rs
│ │ │ │ └── option3.rs
│ │ │ ├── primitive_types/
│ │ │ │ ├── README.md
│ │ │ │ ├── primitive_types1.rs
│ │ │ │ ├── primitive_types2.rs
│ │ │ │ ├── primitive_types3.rs
│ │ │ │ ├── primitive_types4.rs
│ │ │ │ ├── primitive_types5.rs
│ │ │ │ └── primitive_types6.rs
│ │ │ ├── quiz1.rs
│ │ │ ├── quiz2.rs
│ │ │ ├── quiz3.rs
│ │ │ ├── quiz4.rs
│ │ │ ├── standard_library_types/
│ │ │ │ ├── README.md
│ │ │ │ ├── arc1.rs
│ │ │ │ ├── box1.rs
│ │ │ │ ├── iterators1.rs
│ │ │ │ ├── iterators2.rs
│ │ │ │ ├── iterators3.rs
│ │ │ │ ├── iterators4.rs
│ │ │ │ └── iterators5.rs
│ │ │ ├── strings/
│ │ │ │ ├── README.md
│ │ │ │ ├── strings1.rs
│ │ │ │ └── strings2.rs
│ │ │ ├── structs/
│ │ │ │ ├── README.md
│ │ │ │ ├── structs1.rs
│ │ │ │ ├── structs2.rs
│ │ │ │ └── structs3.rs
│ │ │ ├── tests/
│ │ │ │ ├── README.md
│ │ │ │ ├── tests1.rs
│ │ │ │ ├── tests2.rs
│ │ │ │ └── tests3.rs
│ │ │ ├── threads/
│ │ │ │ ├── README.md
│ │ │ │ └── threads1.rs
│ │ │ ├── traits/
│ │ │ │ ├── README.md
│ │ │ │ ├── traits1.rs
│ │ │ │ └── traits2.rs
│ │ │ └── variables/
│ │ │ ├── README.md
│ │ │ ├── variables1.rs
│ │ │ ├── variables2.rs
│ │ │ ├── variables3.rs
│ │ │ ├── variables4.rs
│ │ │ ├── variables5.rs
│ │ │ └── variables6.rs
│ │ ├── info.toml
│ │ ├── install.ps1
│ │ ├── install.sh
│ │ ├── src/
│ │ │ ├── exercise.rs
│ │ │ ├── main.rs
│ │ │ ├── run.rs
│ │ │ ├── ui.rs
│ │ │ └── verify.rs
│ │ └── tests/
│ │ ├── fixture/
│ │ │ ├── failure/
│ │ │ │ ├── compFailure.rs
│ │ │ │ ├── compNoExercise.rs
│ │ │ │ ├── info.toml
│ │ │ │ ├── testFailure.rs
│ │ │ │ └── testNotPassed.rs
│ │ │ ├── state/
│ │ │ │ ├── finished_exercise.rs
│ │ │ │ ├── info.toml
│ │ │ │ ├── pending_exercise.rs
│ │ │ │ └── pending_test_exercise.rs
│ │ │ └── success/
│ │ │ ├── compSuccess.rs
│ │ │ ├── info.toml
│ │ │ └── testSuccess.rs
│ │ └── integration_tests.rs
│ ├── sitemap.xml
│ └── writing-material/
│ ├── books.md
│ ├── courses.md
│ ├── demos_for_learning.md
│ ├── good-sourcecode.md
│ ├── posts/
│ │ ├── Iterator.md
│ │ ├── SIMD.md
│ │ ├── atomic.md
│ │ ├── attributes.md
│ │ ├── fight-with-compiler-check/
│ │ │ ├── borrow.md
│ │ │ └── generic.md
│ │ ├── file.md
│ │ ├── function_signature.md
│ │ ├── generics.md
│ │ ├── hashmap.md
│ │ ├── identifier.md
│ │ ├── images.md
│ │ ├── interview.md
│ │ ├── io.md
│ │ ├── lifetime.md
│ │ ├── lifetime_elision_rules.md
│ │ ├── non-lexical-lifetime.md
│ │ ├── operators.md
│ │ ├── package.md
│ │ ├── performance.md
│ │ ├── plugins.md
│ │ ├── reference.md
│ │ ├── rust-analyser.md
│ │ ├── self-referential.md
│ │ ├── string.md
│ │ ├── system_command.md
│ │ ├── tests/
│ │ │ ├── doc_test.md
│ │ │ ├── integration_test.md
│ │ │ ├── misc.md
│ │ │ └── unit_test.md
│ │ ├── threads.md
│ │ ├── to_resolved.md
│ │ ├── tokio.md
│ │ ├── trivia.md
│ │ └── wasm.md
│ ├── style_guide/
│ │ ├── coding.md
│ │ └── naming.md
│ └── 读者疑惑的点记录.md
├── book.toml
├── ci/
│ └── copy-assets.sh
├── deploy.sh
├── genpdf.sh
├── src/
│ ├── SUMMARY.md
│ ├── about-book.md
│ ├── advance/
│ │ ├── async/
│ │ │ ├── async-await.md
│ │ │ ├── future-excuting.md
│ │ │ ├── getting-started.md
│ │ │ ├── intro.md
│ │ │ ├── multi-futures-simultaneous.md
│ │ │ ├── pain-points-and-workarounds.md
│ │ │ ├── pin-unpin.md
│ │ │ └── web-server.md
│ │ ├── circle-self-ref/
│ │ │ ├── circle-reference.md
│ │ │ ├── intro.md
│ │ │ └── self-referential.md
│ │ ├── concurrency-with-threads/
│ │ │ ├── concurrency-parallelism.md
│ │ │ ├── intro.md
│ │ │ ├── message-passing.md
│ │ │ ├── races.md
│ │ │ ├── ref-counter-lock.md
│ │ │ ├── send-sync.md
│ │ │ ├── sync1.md
│ │ │ ├── sync2.md
│ │ │ └── thread.md
│ │ ├── difficulties/
│ │ │ └── pointer.md
│ │ ├── errors.md
│ │ ├── functional-programing/
│ │ │ ├── closure.md
│ │ │ ├── intro.md
│ │ │ └── iterator.md
│ │ ├── global-variable.md
│ │ ├── hrtb.md
│ │ ├── into-types/
│ │ │ ├── converse.md
│ │ │ ├── custom-type.md
│ │ │ ├── enum-int.md
│ │ │ ├── intro.md
│ │ │ └── sized.md
│ │ ├── intro.md
│ │ ├── lifetime/
│ │ │ ├── advance.md
│ │ │ ├── intro.md
│ │ │ ├── misconceptions.md
│ │ │ └── static.md
│ │ ├── macro.md
│ │ ├── simd.md
│ │ ├── smart-pointer/
│ │ │ ├── box.md
│ │ │ ├── cell-refcell.md
│ │ │ ├── deref.md
│ │ │ ├── drop.md
│ │ │ ├── intro.md
│ │ │ └── rc-arc.md
│ │ └── unsafe/
│ │ ├── inline-asm.md
│ │ ├── intro.md
│ │ ├── superpowers.md
│ │ └── ub.md
│ ├── advance-practice/
│ │ ├── async.md
│ │ ├── bridging-with-sync.md
│ │ ├── channels.md
│ │ ├── design-pattern.md
│ │ ├── frame.md
│ │ ├── getting-startted.md
│ │ ├── graceful-shutdown.md
│ │ ├── intro.md
│ │ ├── io.md
│ │ ├── overview.md
│ │ ├── select.md
│ │ ├── shared-state.md
│ │ ├── spawning.md
│ │ └── stream.md
│ ├── advance-practice1/
│ │ ├── graceful-shutdown.md
│ │ ├── intro.md
│ │ ├── multi-threads.md
│ │ └── web-server.md
│ ├── appendix/
│ │ ├── derive.md
│ │ ├── difficulties.md
│ │ ├── expressions.md
│ │ ├── intro.md
│ │ ├── keywords.md
│ │ ├── operators.md
│ │ ├── prelude.md
│ │ ├── rust-version.md
│ │ └── rust-versions/
│ │ ├── 1.58.md
│ │ ├── 1.59.md
│ │ ├── 1.60.md
│ │ ├── 1.61.md
│ │ ├── 1.62.md
│ │ ├── 1.63.md
│ │ ├── 1.64.md
│ │ ├── 1.65.md
│ │ ├── 1.66.md
│ │ ├── 1.67.md
│ │ ├── 1.68.md
│ │ ├── 1.69.md
│ │ ├── 1.70.md
│ │ ├── 1.71.md
│ │ ├── 1.72.md
│ │ ├── 1.73.md
│ │ ├── 1.74.md
│ │ ├── 1.75.md
│ │ ├── 1.76.md
│ │ ├── 1.77.md
│ │ ├── 1.78.md
│ │ ├── 1.79.md
│ │ ├── 1.80.md
│ │ ├── 1.81.md
│ │ ├── 1.82.md
│ │ ├── 1.83.md
│ │ ├── 1.84.md
│ │ ├── 1.85.md
│ │ ├── 1.86.md
│ │ ├── 1.87.md
│ │ ├── 1.88.md
│ │ ├── 1.89.md
│ │ └── intro.md
│ ├── basic/
│ │ ├── base-type/
│ │ │ ├── char-bool.md
│ │ │ ├── function.md
│ │ │ ├── index.md
│ │ │ ├── numbers.md
│ │ │ └── statement-expression.md
│ │ ├── collections/
│ │ │ ├── hashmap.md
│ │ │ ├── intro.md
│ │ │ └── vector.md
│ │ ├── comment.md
│ │ ├── compound-type/
│ │ │ ├── array.md
│ │ │ ├── enum.md
│ │ │ ├── intro.md
│ │ │ ├── string-slice.md
│ │ │ ├── struct.md
│ │ │ └── tuple.md
│ │ ├── crate-module/
│ │ │ ├── crate.md
│ │ │ ├── intro.md
│ │ │ ├── module.md
│ │ │ └── use.md
│ │ ├── flow-control.md
│ │ ├── formatted-output.md
│ │ ├── intro.md
│ │ ├── lifetime.md
│ │ ├── match-pattern/
│ │ │ ├── all-patterns.md
│ │ │ ├── intro.md
│ │ │ ├── match-if-let.md
│ │ │ ├── option.md
│ │ │ └── pattern-match.md
│ │ ├── method.md
│ │ ├── ownership/
│ │ │ ├── borrowing.md
│ │ │ ├── index.md
│ │ │ └── ownership.md
│ │ ├── result-error/
│ │ │ ├── intro.md
│ │ │ ├── panic.md
│ │ │ └── result.md
│ │ ├── trait/
│ │ │ ├── advance-trait.md
│ │ │ ├── generic.md
│ │ │ ├── intro.md
│ │ │ ├── trait-object.md
│ │ │ └── trait.md
│ │ └── variable.md
│ ├── basic-practice/
│ │ ├── base-features.md
│ │ ├── envs.md
│ │ ├── intro.md
│ │ ├── iterators.md
│ │ ├── refactoring.md
│ │ ├── stderr.md
│ │ └── tests.md
│ ├── beat-ai.md
│ ├── cargo/
│ │ ├── getting-started.md
│ │ ├── git-auth.md
│ │ ├── guide/
│ │ │ ├── build-cache.md
│ │ │ ├── cargo-cache.md
│ │ │ ├── cargo-toml-lock.md
│ │ │ ├── dependencies.md
│ │ │ ├── download-package.md
│ │ │ ├── intro.md
│ │ │ ├── package-layout.md
│ │ │ ├── tests-ci.md
│ │ │ └── why-exist.md
│ │ ├── intro.md
│ │ └── reference/
│ │ ├── build-script/
│ │ │ ├── examples.md
│ │ │ └── intro.md
│ │ ├── cargo-target.md
│ │ ├── configuration.md
│ │ ├── deps-overriding.md
│ │ ├── env.md
│ │ ├── features/
│ │ │ ├── examples.md
│ │ │ └── intro.md
│ │ ├── intro.md
│ │ ├── manifest.md
│ │ ├── package-id.md
│ │ ├── profile.md
│ │ ├── profiles.md
│ │ ├── publishing-on-crates.io.md
│ │ ├── specify-deps.md
│ │ └── workspaces.md
│ ├── community.md
│ ├── compiler/
│ │ ├── fight-with-compiler/
│ │ │ ├── borrowing/
│ │ │ │ ├── borrow-distinct-fields-of-struct.md
│ │ │ │ ├── intro.md
│ │ │ │ └── ref-exist-in-out-fn.md
│ │ │ ├── intro.md
│ │ │ ├── lifetime/
│ │ │ │ ├── closure-with-static.md
│ │ │ │ ├── intro.md
│ │ │ │ ├── loop.md
│ │ │ │ ├── too-long1.md
│ │ │ │ └── too-long2.md
│ │ │ ├── phantom-data.md
│ │ │ └── unconstrained.md
│ │ ├── intro.md
│ │ └── pitfalls/
│ │ ├── arithmetic-overflow.md
│ │ ├── closure-with-lifetime.md
│ │ ├── index.md
│ │ ├── iterator-everywhere.md
│ │ ├── lazy-iterators.md
│ │ ├── main-with-channel-blocked.md
│ │ ├── multiple-mutable-references.md
│ │ ├── stack-overflow.md
│ │ ├── the-disabled-mutability.md
│ │ ├── use-vec-in-for.md
│ │ ├── utf8-performance.md
│ │ └── weird-ranges.md
│ ├── difficulties/
│ │ ├── cow.md
│ │ ├── eq.md
│ │ ├── intro.md
│ │ ├── lifetime.md
│ │ ├── move-copy.md
│ │ ├── pointer.md
│ │ ├── slice.md
│ │ └── string.md
│ ├── first-try/
│ │ ├── cargo.md
│ │ ├── editor.md
│ │ ├── hello-world.md
│ │ ├── installation.md
│ │ ├── intro.md
│ │ ├── slowly-downloading.md
│ │ └── sth-you-should-not-do.md
│ ├── github.md
│ ├── index-list.md
│ ├── into-rust.md
│ ├── libraries/
│ │ ├── command/
│ │ │ ├── intro.md
│ │ │ └── structopt.md
│ │ ├── http/
│ │ │ ├── intro.md
│ │ │ └── reqwest.md
│ │ ├── intro.md
│ │ └── json/
│ │ ├── intro.md
│ │ └── serde.md
│ ├── logs/
│ │ ├── about-log.md
│ │ ├── intro.md
│ │ ├── log.md
│ │ ├── observe/
│ │ │ ├── about-observe.md
│ │ │ ├── intro.md
│ │ │ └── trace.md
│ │ ├── tracing-logger.md
│ │ └── tracing.md
│ ├── practice/
│ │ ├── best-pratice.md
│ │ ├── interview.md
│ │ ├── intro.md
│ │ ├── naming.md
│ │ └── third-party-libs.md
│ ├── practice.md
│ ├── profiling/
│ │ ├── compiler/
│ │ │ ├── attributes.md
│ │ │ ├── intro.md
│ │ │ ├── llvm.md
│ │ │ ├── optimization/
│ │ │ │ ├── intro.md
│ │ │ │ └── option.md
│ │ │ ├── phantom-data.md
│ │ │ └── speed-up.md
│ │ ├── intro.md
│ │ ├── memory/
│ │ │ ├── allocation.md
│ │ │ ├── intro.md
│ │ │ ├── layout.md
│ │ │ ├── pointer-ref.md
│ │ │ ├── uninit.md
│ │ │ └── virtual.md
│ │ ├── performance/
│ │ │ ├── allocator.md
│ │ │ ├── calculate.md
│ │ │ ├── clone-copy.md
│ │ │ ├── cpu-cache.md
│ │ │ ├── deep-into-move.md
│ │ │ ├── early-optimise.md
│ │ │ ├── enum.md
│ │ │ ├── heap-stack.md
│ │ │ ├── intro.md
│ │ │ ├── runtime-check.md
│ │ │ ├── string.md
│ │ │ └── tools.md
│ │ └── profiling/
│ │ └── performance/
│ │ └── benchmark.md
│ ├── rust-weekly.md
│ ├── rustt.md
│ ├── rusty-book.md
│ ├── some-thoughts.md
│ ├── std/
│ │ ├── hashmap.md
│ │ ├── intro.md
│ │ ├── iterator.md
│ │ ├── search.md
│ │ └── vector.md
│ ├── templates/
│ │ ├── files/
│ │ │ ├── dir.md
│ │ │ └── intro.md
│ │ ├── http/
│ │ │ └── intro.md
│ │ └── intro.md
│ ├── test/
│ │ ├── assertion.md
│ │ ├── benchmark.md
│ │ ├── ci.md
│ │ ├── intro.md
│ │ ├── unit-integration-test.md
│ │ └── write-tests.md
│ ├── too-many-lists/
│ │ ├── advanced-lists/
│ │ │ ├── double-singly.md
│ │ │ ├── intro.md
│ │ │ ├── stack-allocated.md
│ │ │ └── unsafe-deque.md
│ │ ├── bad-stack/
│ │ │ ├── basic-operations.md
│ │ │ ├── final-code.md
│ │ │ ├── intro.md
│ │ │ └── layout.md
│ │ ├── deque/
│ │ │ ├── final-code.md
│ │ │ ├── intro.md
│ │ │ ├── iterator.md
│ │ │ ├── layout.md
│ │ │ ├── peek.md
│ │ │ └── symmetric.md
│ │ ├── do-we-need-it.md
│ │ ├── intro.md
│ │ ├── ok-stack/
│ │ │ ├── intro.md
│ │ │ ├── iter.md
│ │ │ ├── itermut.md
│ │ │ ├── peek.md
│ │ │ └── type-optimizing.md
│ │ ├── persistent-stack/
│ │ │ ├── drop-arc.md
│ │ │ ├── intro.md
│ │ │ └── layout.md
│ │ ├── production-unsafe-deque/
│ │ │ ├── basics.md
│ │ │ ├── boring-combinatorics.md
│ │ │ ├── drop-and-panic-safety.md
│ │ │ ├── filling-in-random-bits.md
│ │ │ ├── final-code.md
│ │ │ ├── implementing-cursors.md
│ │ │ ├── intro.md
│ │ │ ├── layout.md
│ │ │ ├── send-sync-and-compile-tests.md
│ │ │ ├── testing-cursors.md
│ │ │ ├── testing.md
│ │ │ └── variance-and-phantomData.md
│ │ └── unsafe-queue/
│ │ ├── basics.md
│ │ ├── extra-junk.md
│ │ ├── final-code.md
│ │ ├── intro.md
│ │ ├── layout.md
│ │ ├── layout2.md
│ │ ├── miri.md
│ │ ├── stacked-borrow.md
│ │ └── testing-stacked-borrow.md
│ └── usecases/
│ ├── aws-rust.md
│ └── intro.md
└── theme/
├── index1.hbs
└── style.css
SYMBOL INDEX (393 symbols across 96 files)
FILE: assets/bigPicture.js
function W (line 1) | function W(){var n=t.getBoundingClientRect();return"transform:translate3...
function q (line 1) | function q(t){var n=A.length-1;if(!u){if(t>0&&E===n||t<0&&!E){if(!I.loop...
function B (line 1) | function B(n){u&&(e[V](m),u=0);var r=A[E];if(r.error)alert(r.error);else...
function P (line 1) | function P(){var t,n,e=.95*window.innerHeight,o=.95*window.innerWidth,i=...
function G (line 1) | function G(t){~[1,4].indexOf(o.readyState)?(U(),setTimeout(function(){o....
function R (line 1) | function R(n){I.noLoader||(n&&j(m,"top:"+t.offsetTop+"px;left:"+t.offset...
function X (line 1) | function X(t){t&&(g.innerHTML=t),j(b,"opacity:"+(t?"1;pointer-events:aut...
function F (line 1) | function F(t){!~C.indexOf(t)&&C.push(t)}
function U (line 1) | function U(t){if(u&&R(),T&&T(),"string"==typeof t)return $(),I.onError?I...
function Y (line 1) | function Y(t){var n=t?t.target:e,i=[b,x,r,a,g,L,S,m];n.blur(),w||~i.inde...
function $ (line 1) | function $(){if((o===c?p:o).removeAttribute("src"),document.body[V](e),e...
function j (line 1) | function j(t,n){t.style.cssText=n}
function s (line 1) | function s(t){var n=document[N]("button");return n.className=t,n.innerHT...
function d (line 1) | function d(t,n){var e=document[N]("button");return e.className="bp-lr",e...
FILE: assets/rustlings-zh/exercises/advanced_errors/advanced_errs1.rs
type ParsePosNonzeroError (line 18) | enum ParsePosNonzeroError {
method from (line 24) | fn from(e: CreationError) -> Self {
type Err (line 37) | type Err = ParsePosNonzeroError;
method from_str (line 38) | fn from_str(s: &str) -> Result<PositiveNonzeroInteger, Self::Err> {
type PositiveNonzeroInteger (line 45) | struct PositiveNonzeroInteger(u64);
method new (line 54) | fn new(value: i64) -> Result<PositiveNonzeroInteger, CreationError> {
type CreationError (line 48) | enum CreationError {
function test_parse_error (line 68) | fn test_parse_error() {
function test_negative (line 77) | fn test_negative() {
function test_zero (line 85) | fn test_zero() {
function test_positive (line 93) | fn test_positive() {
FILE: assets/rustlings-zh/exercises/advanced_errors/advanced_errs2.rs
type ParseClimateError (line 29) | enum ParseClimateError {
method from (line 40) | fn from(e: ParseIntError) -> Self {
method from (line 48) | fn from(e: ParseFloatError) -> Self {
method fmt (line 61) | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
type Climate (line 72) | struct Climate {
type Err (line 87) | type Err = ParseClimateError;
method from_str (line 90) | fn from_str(s: &str) -> Result<Self, Self::Err> {
function main (line 105) | fn main() -> Result<(), Box<dyn Error>> {
function test_empty (line 115) | fn test_empty() {
function test_short (line 121) | fn test_short() {
function test_long (line 127) | fn test_long() {
function test_no_city (line 133) | fn test_no_city() {
function test_parse_int_neg (line 139) | fn test_parse_int_neg() {
function test_parse_int_bad (line 153) | fn test_parse_int_bad() {
function test_parse_float (line 167) | fn test_parse_float() {
function test_parse_good (line 181) | fn test_parse_good() {
function test_downcast (line 194) | fn test_downcast() {
FILE: assets/rustlings-zh/exercises/clippy/clippy1.rs
function main (line 11) | fn main() {
FILE: assets/rustlings-zh/exercises/clippy/clippy2.rs
function main (line 6) | fn main() {
FILE: assets/rustlings-zh/exercises/collections/hashmap1.rs
function fruit_basket (line 14) | fn fruit_basket() -> HashMap<String, u32> {
function at_least_three_types_of_fruits (line 30) | fn at_least_three_types_of_fruits() {
function at_least_five_fruits (line 36) | fn at_least_five_fruits() {
FILE: assets/rustlings-zh/exercises/collections/hashmap2.rs
type Fruit (line 15) | enum Fruit {
function fruit_basket (line 23) | fn fruit_basket(basket: &mut HashMap<Fruit, u32>) {
function get_fruit_basket (line 42) | fn get_fruit_basket() -> HashMap<Fruit, u32> {
function test_given_fruits_are_not_modified (line 52) | fn test_given_fruits_are_not_modified() {
function at_least_five_types_of_fruits (line 61) | fn at_least_five_types_of_fruits() {
function greater_than_eleven_fruits (line 69) | fn greater_than_eleven_fruits() {
FILE: assets/rustlings-zh/exercises/collections/vec1.rs
function array_and_vec (line 8) | fn array_and_vec() -> ([i32; 4], Vec<i32>) {
function test_array_and_vec_similarity (line 20) | fn test_array_and_vec_similarity() {
FILE: assets/rustlings-zh/exercises/collections/vec2.rs
function vec_loop (line 10) | fn vec_loop(mut v: Vec<i32>) -> Vec<i32> {
function test_vec_loop (line 24) | fn test_vec_loop() {
FILE: assets/rustlings-zh/exercises/conversions/as_ref_mut.rs
function byte_counter (line 9) | fn byte_counter<T>(arg: T) -> usize {
function char_counter (line 15) | fn char_counter<T>(arg: T) -> usize {
function main (line 19) | fn main() {
function different_counts (line 30) | fn different_counts() {
function same_counts (line 36) | fn same_counts() {
function different_counts_using_string (line 42) | fn different_counts_using_string() {
function same_counts_using_string (line 48) | fn same_counts_using_string() {
FILE: assets/rustlings-zh/exercises/conversions/from_into.rs
type Person (line 5) | struct Person {
method from (line 39) | fn from(s: &str) -> Person {
method default (line 13) | fn default() -> Person {
function main (line 43) | fn main() {
function test_default (line 56) | fn test_default() {
function test_bad_convert (line 63) | fn test_bad_convert() {
function test_good_convert (line 70) | fn test_good_convert() {
function test_bad_age (line 77) | fn test_bad_age() {
function test_missing_comma_and_age (line 85) | fn test_missing_comma_and_age() {
function test_missing_age (line 92) | fn test_missing_age() {
function test_missing_name (line 99) | fn test_missing_name() {
function test_missing_name_and_age (line 106) | fn test_missing_name_and_age() {
function test_missing_name_and_invalid_age (line 113) | fn test_missing_name_and_invalid_age() {
function test_trailing_comma (line 120) | fn test_trailing_comma() {
function test_trailing_comma_and_some_string (line 127) | fn test_trailing_comma_and_some_string() {
FILE: assets/rustlings-zh/exercises/conversions/from_str.rs
type Person (line 11) | struct Person {
type ParsePersonError (line 18) | enum ParsePersonError {
type Err (line 42) | type Err = ParsePersonError;
method from_str (line 43) | fn from_str(s: &str) -> Result<Person, Self::Err> {
function main (line 47) | fn main() {
function empty_input (line 57) | fn empty_input() {
function good_input (line 61) | fn good_input() {
function missing_age (line 69) | fn missing_age() {
function invalid_age (line 77) | fn invalid_age() {
function missing_comma_and_age (line 85) | fn missing_comma_and_age() {
function missing_name (line 90) | fn missing_name() {
function missing_name_and_age (line 95) | fn missing_name_and_age() {
function missing_name_and_invalid_age (line 103) | fn missing_name_and_invalid_age() {
function trailing_comma (line 111) | fn trailing_comma() {
function trailing_comma_and_some_string (line 116) | fn trailing_comma_and_some_string() {
FILE: assets/rustlings-zh/exercises/conversions/try_from_into.rs
type Color (line 9) | struct Color {
type Error (line 37) | type Error = IntoColorError;
method try_from (line 38) | fn try_from(tuple: (i16, i16, i16)) -> Result<Self, Self::Error> {
type Error (line 44) | type Error = IntoColorError;
method try_from (line 45) | fn try_from(arr: [i16; 3]) -> Result<Self, Self::Error> {
type Error (line 51) | type Error = IntoColorError;
method try_from (line 52) | fn try_from(slice: &[i16]) -> Result<Self, Self::Error> {
type IntoColorError (line 17) | enum IntoColorError {
function main (line 56) | fn main() {
function test_tuple_out_of_range_positive (line 79) | fn test_tuple_out_of_range_positive() {
function test_tuple_out_of_range_negative (line 86) | fn test_tuple_out_of_range_negative() {
function test_tuple_sum (line 93) | fn test_tuple_sum() {
function test_tuple_correct (line 100) | fn test_tuple_correct() {
function test_array_out_of_range_positive (line 113) | fn test_array_out_of_range_positive() {
function test_array_out_of_range_negative (line 118) | fn test_array_out_of_range_negative() {
function test_array_sum (line 123) | fn test_array_sum() {
function test_array_correct (line 128) | fn test_array_correct() {
function test_slice_out_of_range_positive (line 141) | fn test_slice_out_of_range_positive() {
function test_slice_out_of_range_negative (line 149) | fn test_slice_out_of_range_negative() {
function test_slice_sum (line 157) | fn test_slice_sum() {
function test_slice_correct (line 165) | fn test_slice_correct() {
function test_slice_excess_length (line 179) | fn test_slice_excess_length() {
function test_slice_insufficient_length (line 184) | fn test_slice_insufficient_length() {
FILE: assets/rustlings-zh/exercises/conversions/using_as.rs
function average (line 10) | fn average(values: &[f64]) -> f64 {
function main (line 15) | fn main() {
function returns_proper_type_and_value (line 25) | fn returns_proper_type_and_value() {
FILE: assets/rustlings-zh/exercises/enums/enums1.rs
type Message (line 7) | enum Message {
function main (line 11) | fn main() {
FILE: assets/rustlings-zh/exercises/enums/enums2.rs
type Message (line 7) | enum Message {
method call (line 12) | fn call(&self) {
function main (line 17) | fn main() {
FILE: assets/rustlings-zh/exercises/enums/enums3.rs
type Message (line 6) | enum Message {
type Point (line 10) | struct Point {
type State (line 15) | struct State {
method change_color (line 22) | fn change_color(&mut self, color: (u8, u8, u8)) {
method quit (line 26) | fn quit(&mut self) {
method echo (line 30) | fn echo(&self, s: String) {
method move_position (line 34) | fn move_position(&mut self, p: Point) {
method process (line 38) | fn process(&mut self, message: Message) {
function test_match_message_call (line 48) | fn test_match_message_call() {
FILE: assets/rustlings-zh/exercises/error_handling/errors1.rs
function generate_nametag_text (line 9) | pub fn generate_nametag_text(name: String) -> Option<String> {// 译:生成个性签名
function generates_nametag_text_for_a_nonempty_name (line 25) | fn generates_nametag_text_for_a_nonempty_name() {// 译:用一个非空名称生成一段个性签名
function explains_why_generating_nametag_text_fails (line 33) | fn explains_why_generating_nametag_text_fails() {// 译:说明为什么个性签名生成失败了
FILE: assets/rustlings-zh/exercises/error_handling/errors2.rs
function total_cost (line 19) | pub fn total_cost(item_quantity: &str) -> Result<i32, ParseIntError> {
function item_quantity_is_a_valid_number (line 32) | fn item_quantity_is_a_valid_number() {
function item_quantity_is_an_invalid_number (line 37) | fn item_quantity_is_an_invalid_number() {
FILE: assets/rustlings-zh/exercises/error_handling/errors3.rs
function main (line 10) | fn main() {
function total_cost (line 24) | pub fn total_cost(item_quantity: &str) -> Result<i32, ParseIntError> {
FILE: assets/rustlings-zh/exercises/error_handling/errors4.rs
type PositiveNonzeroInteger (line 7) | struct PositiveNonzeroInteger(u64);
method new (line 16) | fn new(value: i64) -> Result<PositiveNonzeroInteger, CreationError> {
type CreationError (line 10) | enum CreationError {
function test_creation (line 22) | fn test_creation() {
FILE: assets/rustlings-zh/exercises/error_handling/errors5.rs
function main (line 14) | fn main() -> Result<(), ParseIntError> {
type PositiveNonzeroInteger (line 24) | struct PositiveNonzeroInteger(u64);
method new (line 33) | fn new(value: i64) -> Result<PositiveNonzeroInteger, CreationError> {
type CreationError (line 27) | enum CreationError {
method fmt (line 44) | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
FILE: assets/rustlings-zh/exercises/error_handling/errors6.rs
type ParsePosNonzeroError (line 16) | enum ParsePosNonzeroError {
method from_creation (line 22) | fn from_creation(err: CreationError) -> ParsePosNonzeroError {
function parse_pos_nonzero (line 28) | fn parse_pos_nonzero(s: &str)
type PositiveNonzeroInteger (line 40) | struct PositiveNonzeroInteger(u64);
method new (line 49) | fn new(value: i64) -> Result<PositiveNonzeroInteger, CreationError> {
type CreationError (line 43) | enum CreationError {
function test_parse_error (line 63) | fn test_parse_error() {
function test_negative (line 72) | fn test_negative() {
function test_zero (line 80) | fn test_zero() {
function test_positive (line 88) | fn test_positive() {
FILE: assets/rustlings-zh/exercises/functions/functions1.rs
function main (line 7) | fn main() {
FILE: assets/rustlings-zh/exercises/functions/functions2.rs
function main (line 7) | fn main() {
function call_me (line 11) | fn call_me(num:) {
FILE: assets/rustlings-zh/exercises/functions/functions3.rs
function main (line 7) | fn main() {
function call_me (line 11) | fn call_me(num: u32) {
FILE: assets/rustlings-zh/exercises/functions/functions4.rs
function main (line 10) | fn main() {
function sale_price (line 15) | fn sale_price(price: i32) -> {
function is_even (line 23) | fn is_even(num: i32) -> bool {
FILE: assets/rustlings-zh/exercises/functions/functions5.rs
function main (line 7) | fn main() {
function square (line 12) | fn square(num: i32) -> i32 {
FILE: assets/rustlings-zh/exercises/generics/generics1.rs
function main (line 8) | fn main() {
FILE: assets/rustlings-zh/exercises/generics/generics2.rs
type Wrapper (line 8) | struct Wrapper {
method new (line 13) | pub fn new(value: u32) -> Self {
function store_u32_in_wrapper (line 23) | fn store_u32_in_wrapper() {
function store_str_in_wrapper (line 28) | fn store_str_in_wrapper() {
FILE: assets/rustlings-zh/exercises/generics/generics3.rs
type ReportCard (line 12) | pub struct ReportCard {
method print (line 19) | pub fn print(&self) -> String {
function generate_numeric_report_card (line 30) | fn generate_numeric_report_card() {
function generate_alphabetic_report_card (line 43) | fn generate_alphabetic_report_card() {
FILE: assets/rustlings-zh/exercises/if/if1.rs
function bigger (line 5) | pub fn bigger(a: i32, b: i32) -> i32 {
function ten_is_bigger_than_eight (line 19) | fn ten_is_bigger_than_eight() {
function fortytwo_is_bigger_than_thirtytwo (line 24) | fn fortytwo_is_bigger_than_thirtytwo() {
FILE: assets/rustlings-zh/exercises/if/if2.rs
function fizz_if_foo (line 9) | pub fn fizz_if_foo(fizzish: &str) -> &str {
function foo_for_fizz (line 23) | fn foo_for_fizz() {
function bar_for_fuzz (line 28) | fn bar_for_fuzz() {
function default_to_baz (line 33) | fn default_to_baz() {
FILE: assets/rustlings-zh/exercises/macros/macros1.rs
function main (line 12) | fn main() {
FILE: assets/rustlings-zh/exercises/macros/macros2.rs
function main (line 6) | fn main() {
FILE: assets/rustlings-zh/exercises/macros/macros3.rs
function main (line 15) | fn main() {
FILE: assets/rustlings-zh/exercises/macros/macros4.rs
function main (line 15) | fn main() {
FILE: assets/rustlings-zh/exercises/modules/modules1.rs
function get_secret_recipe (line 8) | fn get_secret_recipe() -> String {
function make_sausage (line 12) | fn make_sausage() {
function main (line 18) | fn main() {
FILE: assets/rustlings-zh/exercises/modules/modules2.rs
constant PEAR (line 15) | pub const PEAR: &'static str = "Pear";
constant APPLE (line 16) | pub const APPLE: &'static str = "Apple";
constant CUCUMBER (line 20) | pub const CUCUMBER: &'static str = "Cucumber";
constant CARROT (line 21) | pub const CARROT: &'static str = "Carrot";
function main (line 25) | fn main() {
FILE: assets/rustlings-zh/exercises/modules/modules3.rs
function main (line 11) | fn main() {
FILE: assets/rustlings-zh/exercises/move_semantics/move_semantics1.rs
function main (line 6) | fn main() {
function fill_vec (line 18) | fn fill_vec(vec: Vec<i32>) -> Vec<i32> {
FILE: assets/rustlings-zh/exercises/move_semantics/move_semantics2.rs
function main (line 7) | fn main() {
function fill_vec (line 20) | fn fill_vec(vec: Vec<i32>) -> Vec<i32> {
FILE: assets/rustlings-zh/exercises/move_semantics/move_semantics3.rs
function main (line 8) | fn main() {
function fill_vec (line 20) | fn fill_vec(vec: Vec<i32>) -> Vec<i32> {
FILE: assets/rustlings-zh/exercises/move_semantics/move_semantics4.rs
function main (line 8) | fn main() {
function fill_vec (line 21) | fn fill_vec() -> Vec<i32> {
FILE: assets/rustlings-zh/exercises/move_semantics/move_semantics5.rs
function main (line 7) | fn main() {
FILE: assets/rustlings-zh/exercises/option/option1.rs
function print_number (line 7) | fn print_number(maybe_number: Option<u16>) {
function main (line 11) | fn main() {
FILE: assets/rustlings-zh/exercises/option/option2.rs
function main (line 6) | fn main() {
FILE: assets/rustlings-zh/exercises/option/option3.rs
type Point (line 6) | struct Point {
function main (line 11) | fn main() {
FILE: assets/rustlings-zh/exercises/primitive_types/primitive_types1.rs
function main (line 7) | fn main() {
FILE: assets/rustlings-zh/exercises/primitive_types/primitive_types2.rs
function main (line 7) | fn main() {
FILE: assets/rustlings-zh/exercises/primitive_types/primitive_types3.rs
function main (line 7) | fn main() {
FILE: assets/rustlings-zh/exercises/primitive_types/primitive_types4.rs
function slice_out_of_array (line 8) | fn slice_out_of_array() {
FILE: assets/rustlings-zh/exercises/primitive_types/primitive_types5.rs
function main (line 7) | fn main() {
FILE: assets/rustlings-zh/exercises/primitive_types/primitive_types6.rs
function indexing_tuple (line 9) | fn indexing_tuple() {
FILE: assets/rustlings-zh/exercises/quiz1.rs
function verify_test (line 17) | fn verify_test() {
FILE: assets/rustlings-zh/exercises/quiz2.rs
function string_slice (line 12) | fn string_slice(arg: &str) {
function string (line 15) | fn string(arg: String) {
function main (line 19) | fn main() {
FILE: assets/rustlings-zh/exercises/quiz3.rs
function times_two (line 12) | pub fn times_two(num: i32) -> i32 {
function returns_twice_of_positive_numbers (line 21) | fn returns_twice_of_positive_numbers() {
function returns_twice_of_negative_numbers (line 26) | fn returns_twice_of_negative_numbers() {
FILE: assets/rustlings-zh/exercises/quiz4.rs
function test_my_macro_world (line 15) | fn test_my_macro_world() {
function test_my_macro_goodbye (line 20) | fn test_my_macro_goodbye() {
FILE: assets/rustlings-zh/exercises/standard_library_types/arc1.rs
function main (line 27) | fn main() {
FILE: assets/rustlings-zh/exercises/standard_library_types/box1.rs
type List (line 22) | pub enum List {
function main (line 27) | fn main() {
function create_empty_list (line 35) | pub fn create_empty_list() -> List {
function create_non_empty_list (line 39) | pub fn create_non_empty_list() -> List {
function test_create_empty_list (line 48) | fn test_create_empty_list() {
function test_create_non_empty_list (line 53) | fn test_create_non_empty_list() {
FILE: assets/rustlings-zh/exercises/standard_library_types/iterators1.rs
function main (line 13) | fn main () {
FILE: assets/rustlings-zh/exercises/standard_library_types/iterators2.rs
function capitalize_first (line 11) | pub fn capitalize_first(input: &str) -> String {
function capitalize_words_vector (line 23) | pub fn capitalize_words_vector(words: &[&str]) -> Vec<String> {
function capitalize_words_string (line 31) | pub fn capitalize_words_string(words: &[&str]) -> String {
function test_success (line 40) | fn test_success() {
function test_empty (line 45) | fn test_empty() {
function test_iterate_string_vec (line 50) | fn test_iterate_string_vec() {
function test_iterate_into_string (line 56) | fn test_iterate_into_string() {
FILE: assets/rustlings-zh/exercises/standard_library_types/iterators3.rs
type DivisionError (line 12) | pub enum DivisionError {
type NotDivisibleError (line 18) | pub struct NotDivisibleError {
function divide (line 25) | pub fn divide(a: i32, b: i32) -> Result<i32, DivisionError> {}
function result_with_list (line 29) | fn result_with_list() -> () {
function list_of_results (line 36) | fn list_of_results() -> () {
function test_success (line 46) | fn test_success() {
function test_not_divisible (line 51) | fn test_not_divisible() {
function test_divide_by_0 (line 62) | fn test_divide_by_0() {
function test_divide_0_by_something (line 67) | fn test_divide_0_by_something() {
function test_result_with_list (line 72) | fn test_result_with_list() {
function test_list_of_results (line 77) | fn test_list_of_results() {
FILE: assets/rustlings-zh/exercises/standard_library_types/iterators4.rs
function factorial (line 5) | pub fn factorial(num: u64) -> u64 {
function factorial_of_1 (line 22) | fn factorial_of_1() {
function factorial_of_2 (line 26) | fn factorial_of_2() {
function factorial_of_4 (line 31) | fn factorial_of_4() {
FILE: assets/rustlings-zh/exercises/standard_library_types/iterators5.rs
type Progress (line 18) | enum Progress {
function count_for (line 24) | fn count_for(map: &HashMap<String, Progress>, value: Progress) -> usize {
function count_iterator (line 34) | fn count_iterator(map: &HashMap<String, Progress>, value: Progress) -> u...
function count_collection_for (line 39) | fn count_collection_for(collection: &[HashMap<String, Progress>], value:...
function count_collection_iterator (line 51) | fn count_collection_iterator(collection: &[HashMap<String, Progress>], v...
function count_complete (line 62) | fn count_complete() {
function count_equals_for (line 68) | fn count_equals_for() {
function count_collection_complete (line 77) | fn count_collection_complete() {
function count_collection_equals_for (line 86) | fn count_collection_equals_for() {
function get_map (line 94) | fn get_map() -> HashMap<String, Progress> {
function get_vec_map (line 108) | fn get_vec_map() -> Vec<HashMap<String, Progress>> {
FILE: assets/rustlings-zh/exercises/strings/strings1.rs
function main (line 7) | fn main() {
function current_favorite_color (line 13) | fn current_favorite_color() -> String {
FILE: assets/rustlings-zh/exercises/strings/strings2.rs
function main (line 7) | fn main() {
function is_a_color_word (line 17) | fn is_a_color_word(attempt: &str) -> bool {
FILE: assets/rustlings-zh/exercises/structs/structs1.rs
type ColorClassicStruct (line 6) | struct ColorClassicStruct {
type ColorTupleStruct (line 10) | struct ColorTupleStruct(/* TODO: 一些东西需要在这里 */);
type UnitStruct (line 13) | struct UnitStruct;
function classic_c_structs (line 20) | fn classic_c_structs() {
function tuple_structs (line 29) | fn tuple_structs() {
function unit_structs (line 38) | fn unit_structs() {
FILE: assets/rustlings-zh/exercises/structs/structs2.rs
type Order (line 7) | struct Order {
function create_order_template (line 17) | fn create_order_template() -> Order {
function your_order (line 34) | fn your_order() {
FILE: assets/rustlings-zh/exercises/structs/structs3.rs
type Package (line 10) | struct Package {// 译:包裹
method new (line 17) | fn new(sender_country: String, recipient_country: String, weight_in_gr...
method is_international (line 29) | fn is_international(&self) -> ??? {// 译:是否是国际上的
method get_fees (line 33) | fn get_fees(&self, cents_per_gram: i32) -> ??? {// 译:获取所需费用
function fail_creating_weightless_package (line 44) | fn fail_creating_weightless_package() {// 译:失败地创建没有重量的包裹
function create_international_package (line 52) | fn create_international_package() {// 译:创建国际上的包裹
function create_local_package (line 62) | fn create_local_package() {
function calculate_transport_fees (line 72) | fn calculate_transport_fees() {// 译:计算运输费
FILE: assets/rustlings-zh/exercises/tests/tests1.rs
function you_can_assert (line 14) | fn you_can_assert() {
FILE: assets/rustlings-zh/exercises/tests/tests2.rs
function you_can_assert_eq (line 10) | fn you_can_assert_eq() {
FILE: assets/rustlings-zh/exercises/tests/tests3.rs
function is_even (line 8) | pub fn is_even(num: i32) -> bool {
function is_true_when_even (line 17) | fn is_true_when_even() {// 偶数将返回 true
function is_false_when_odd (line 22) | fn is_false_when_odd() {// 奇数将返回 false
FILE: assets/rustlings-zh/exercises/threads/threads1.rs
type JobStatus (line 15) | struct JobStatus {
function main (line 19) | fn main() {
FILE: assets/rustlings-zh/exercises/traits/traits1.rs
type AppendBar (line 11) | trait AppendBar {
method append_bar (line 12) | fn append_bar(self) -> Self;
function main (line 19) | fn main() {
function is_foo_bar (line 30) | fn is_foo_bar() {
function is_bar_bar (line 35) | fn is_bar_bar() {
FILE: assets/rustlings-zh/exercises/traits/traits2.rs
type AppendBar (line 11) | trait AppendBar {
method append_bar (line 12) | fn append_bar(self) -> Self;
function is_vec_pop_eq_bar (line 22) | fn is_vec_pop_eq_bar() {
FILE: assets/rustlings-zh/exercises/variables/variables1.rs
function main (line 13) | fn main() {
FILE: assets/rustlings-zh/exercises/variables/variables2.rs
function main (line 7) | fn main() {
FILE: assets/rustlings-zh/exercises/variables/variables3.rs
function main (line 7) | fn main() {
FILE: assets/rustlings-zh/exercises/variables/variables4.rs
function main (line 7) | fn main() {
FILE: assets/rustlings-zh/exercises/variables/variables5.rs
function main (line 7) | fn main() {
FILE: assets/rustlings-zh/exercises/variables/variables6.rs
function main (line 8) | fn main() {
FILE: assets/rustlings-zh/src/exercise.rs
constant RUSTC_COLOR_ARGS (line 10) | const RUSTC_COLOR_ARGS: &[&str] = &["--color", "always"];
constant I_AM_DONE_REGEX (line 11) | const I_AM_DONE_REGEX: &str = r"(?m)^\s*///?\s*I\s+AM\s+NOT\s+DONE";
constant CONTEXT (line 12) | const CONTEXT: usize = 2;
constant CLIPPY_CARGO_TOML_PATH (line 13) | const CLIPPY_CARGO_TOML_PATH: &str = "./exercises/clippy/Cargo.toml";
function temp_file (line 17) | fn temp_file() -> String {
type Mode (line 29) | pub enum Mode {
type ExerciseList (line 39) | pub struct ExerciseList {
type Exercise (line 46) | pub struct Exercise {
method compile (line 109) | pub fn compile(&self) -> Result<CompiledExercise, ExerciseOutput> {
method run (line 177) | fn run(&self) -> Result<ExerciseOutput, ExerciseOutput> {
method state (line 199) | pub fn state(&self) -> State {
method looks_done (line 247) | pub fn looks_done(&self) -> bool {
type State (line 60) | pub enum State {
type ContextLine (line 69) | pub struct ContextLine {
type CompiledExercise (line 79) | pub struct CompiledExercise<'a> {
function run (line 86) | pub fn run(&self) -> Result<ExerciseOutput, ExerciseOutput> {
type ExerciseOutput (line 93) | pub struct ExerciseOutput {
type FileHandle (line 100) | struct FileHandle;
method drop (line 103) | fn drop(&mut self) {
method fmt (line 253) | fn fmt(&self, f: &mut Formatter) -> fmt::Result {
function clean (line 259) | fn clean() {
function test_clean (line 269) | fn test_clean() {
function test_pending_state (line 283) | fn test_pending_state() {
function test_finished_exercise (line 324) | fn test_finished_exercise() {
function test_exercise_with_output (line 336) | fn test_exercise_with_output() {
FILE: assets/rustlings-zh/src/main.rs
constant VERSION (line 27) | const VERSION: &str = "4.6.0";
type Args (line 31) | struct Args {
type Subcommands (line 44) | enum Subcommands {
type VerifyArgs (line 55) | struct VerifyArgs {}
type WatchArgs (line 60) | struct WatchArgs {}
type RunArgs (line 65) | struct RunArgs {
type HintArgs (line 74) | struct HintArgs {
type ListArgs (line 83) | struct ListArgs {
function main (line 102) | fn main() {
function spawn_watch_shell (line 274) | fn spawn_watch_shell(
function find_exercise (line 311) | fn find_exercise<'a>(name: &str, exercises: &'a [Exercise]) -> &'a Exerc...
type WatchStatus (line 332) | enum WatchStatus {
function watch (line 337) | fn watch(exercises: &[Exercise], verbose: bool) -> notify::Result<WatchS...
function rustc_exists (line 397) | fn rustc_exists() -> bool {
FILE: assets/rustlings-zh/src/run.rs
function run (line 9) | pub fn run(exercise: &Exercise, verbose: bool) -> Result<(), ()> {
function compile_and_run (line 21) | fn compile_and_run(exercise: &Exercise) -> Result<(), ()> {
FILE: assets/rustlings-zh/src/verify.rs
function verify (line 11) | pub fn verify<'a>(
type RunMode (line 28) | enum RunMode {
function test (line 34) | pub fn test(exercise: &Exercise, verbose: bool) -> Result<(), ()> {
function compile_only (line 40) | fn compile_only(exercise: &Exercise) -> Result<bool, ()> {
function compile_and_run_interactively (line 53) | fn compile_and_run_interactively(exercise: &Exercise) -> Result<bool, ()> {
function compile_and_test (line 81) | fn compile_and_test(exercise: &Exercise, run_mode: RunMode, verbose: boo...
function compile (line 115) | fn compile<'a, 'b>(
function prompt_for_completion (line 135) | fn prompt_for_completion(exercise: &Exercise, prompt_output: Option<Stri...
function separator (line 195) | fn separator() -> console::StyledObject<&'static str> {
FILE: assets/rustlings-zh/tests/fixture/failure/compFailure.rs
function main (line 1) | fn main() {
FILE: assets/rustlings-zh/tests/fixture/failure/compNoExercise.rs
function main (line 1) | fn main() {
FILE: assets/rustlings-zh/tests/fixture/failure/testFailure.rs
function passing (line 2) | fn passing() {
FILE: assets/rustlings-zh/tests/fixture/failure/testNotPassed.rs
function not_passing (line 2) | fn not_passing() {
FILE: assets/rustlings-zh/tests/fixture/state/finished_exercise.rs
function main (line 3) | fn main() {
FILE: assets/rustlings-zh/tests/fixture/state/pending_exercise.rs
function main (line 5) | fn main() {
FILE: assets/rustlings-zh/tests/fixture/state/pending_test_exercise.rs
function it_works (line 4) | fn it_works() {}
FILE: assets/rustlings-zh/tests/fixture/success/compSuccess.rs
function main (line 1) | fn main() {
FILE: assets/rustlings-zh/tests/fixture/success/testSuccess.rs
function passing (line 2) | fn passing() {
FILE: assets/rustlings-zh/tests/integration_tests.rs
function runs_without_arguments (line 9) | fn runs_without_arguments() {
function fails_when_in_wrong_dir (line 15) | fn fails_when_in_wrong_dir() {
function verify_all_success (line 24) | fn verify_all_success() {
function verify_fails_if_some_fails (line 34) | fn verify_fails_if_some_fails() {
function run_single_compile_success (line 44) | fn run_single_compile_success() {
function run_single_compile_failure (line 54) | fn run_single_compile_failure() {
function run_single_test_success (line 64) | fn run_single_test_success() {
function run_single_test_failure (line 74) | fn run_single_test_failure() {
function run_single_test_not_passed (line 84) | fn run_single_test_not_passed() {
function run_single_test_no_filename (line 94) | fn run_single_test_no_filename() {
function run_single_test_no_exercise (line 104) | fn run_single_test_no_exercise() {
function get_hint_for_single_test (line 114) | fn get_hint_for_single_test() {
function all_exercises_require_confirmation (line 125) | fn all_exercises_require_confirmation() {
function run_compile_exercise_does_not_prompt (line 147) | fn run_compile_exercise_does_not_prompt() {
function run_test_exercise_does_not_prompt (line 158) | fn run_test_exercise_does_not_prompt() {
function run_single_test_success_with_output (line 169) | fn run_single_test_success_with_output() {
function run_single_test_success_without_output (line 180) | fn run_single_test_success_without_output() {
function run_rustlings_list (line 191) | fn run_rustlings_list() {
function run_rustlings_list_no_pending (line 201) | fn run_rustlings_list_no_pending() {
function run_rustlings_list_both_done_and_pending (line 212) | fn run_rustlings_list_both_done_and_pending() {
function run_rustlings_list_without_pending (line 223) | fn run_rustlings_list_without_pending() {
function run_rustlings_list_without_done (line 234) | fn run_rustlings_list_without_done() {
Condensed preview — 535 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (2,038K chars).
[
{
"path": ".github/workflows/ci.yml",
"chars": 604,
"preview": "name: CI\n\non:\n push:\n branches:\n - main\n\n pull_request:\n branches:\n - main\n\njobs:\n test:\n name: te"
},
{
"path": ".github/workflows/deploy.yml",
"chars": 973,
"preview": "name: Deploy\n\non:\n push:\n branches:\n - main\n\n pull_request:\n branches:\n - main\n\ndefaults:\n run:\n s"
},
{
"path": ".gitignore",
"chars": 36,
"preview": ".DS_Store\nbook\nChangelog.md\ndump.rdb"
},
{
"path": "README.md",
"chars": 4654,
"preview": "<h1 align=\"center\">Rust语言圣经</h1>\n\n<div align=\"center\">\n <img src=\"https://github.com/sunface/rust-course/blob/main/as"
},
{
"path": "assets/CNAME",
"chars": 9,
"preview": "course.rs"
},
{
"path": "assets/bigPicture.js",
"chars": 8898,
"preview": "var BigPicture=function(){var t,n,e,o,i,r,a,c,p,s,l,d,u,f,m,b,g,h,x,v,y,w,_,T,k,M,S,L,E,A,H,z,I,C=[],D={},O=\"appendChild"
},
{
"path": "assets/custom.js",
"chars": 5366,
"preview": "var initAll = function () {\n var path = window.location.pathname;\n if (path.endsWith(\"/print.html\")) {\n ret"
},
{
"path": "assets/rustlings-zh/.all-contributorsrc",
"chars": 27828,
"preview": "{\n \"files\": [\n \"README.md\"\n ],\n \"imageSize\": 100,\n \"commit\": false,\n \"contributors\": [\n {\n \"login\": \"car"
},
{
"path": "assets/rustlings-zh/.clog.toml",
"chars": 88,
"preview": "[clog]\n\nrepository = \"https://github.com/rust-lang/rustlings\"\nchangelog = \"CHANGELOG.md\""
},
{
"path": "assets/rustlings-zh/.editorconfig",
"chars": 102,
"preview": "root = true\n\n[*.rs]\nend_of_line = lf\ninsert_final_newfile = true\nindent_style = space\nindent_size = 4\n"
},
{
"path": "assets/rustlings-zh/.gitignore",
"chars": 119,
"preview": "*.swp\ntarget/\n**/*.rs.bk\n.DS_Store\n*.pdb\nexercises/clippy/Cargo.toml\nexercises/clippy/Cargo.lock\n.idea/\n.vscode\n*.iml\n\n"
},
{
"path": "assets/rustlings-zh/.gitpod.yml",
"chars": 175,
"preview": "tasks:\n - init: /workspace/rustlings/install.sh\n command: /workspace/.cargo/bin/rustlings watch\n\nvscode:\n extension"
},
{
"path": "assets/rustlings-zh/.replit",
"chars": 104,
"preview": "language = \"rust\"\nrun = \"[ -x ~/.cargo/bin/rustlings ] && ~/.cargo/bin/rustlings watch || ./install.sh\"\n"
},
{
"path": "assets/rustlings-zh/CHANGELOG.md",
"chars": 32701,
"preview": "<a name=\"4.6.0\"></a>\n## 4.6.0 (2021-09-25)\n\n\n#### Features\n\n* add advanced_errs2 ([abd6b70c](https://github.com/rust-l"
},
{
"path": "assets/rustlings-zh/CONTRIBUTING.md",
"chars": 4198,
"preview": "## Contributing to Rustlings\n\nFirst off, thanks for taking the time to contribute!! ❤️\n\n### Quick Reference\n\nI want to.."
},
{
"path": "assets/rustlings-zh/Cargo.toml",
"chars": 376,
"preview": "[package]\nname = \"rustlings\"\nversion = \"4.6.0\"\nauthors = []\nedition = \"2021\"\n\n[dependencies]\nargh = \"0.1.4\"\nindicatif = "
},
{
"path": "assets/rustlings-zh/LICENSE",
"chars": 1095,
"preview": "The MIT License (MIT)\n\nCopyright (c) 2016 Carol (Nichols || Goulding)\n\nPermission is hereby granted, free of charge, to "
},
{
"path": "assets/rustlings-zh/README.md",
"chars": 1447,
"preview": "# rustlings-zh 🦀❤️\n本项目是 [rustlings](https://github.com/rust-lang/rustlings) 的中文翻译版。\n \n## 开始使用\n\n_注意: 如果你在使用 macOS,确保已经安"
},
{
"path": "assets/rustlings-zh/default_out.txt",
"chars": 690,
"preview": "感谢安装 Rustlings!\n\n你还没有任何使用经验?不用担心,Rustlings 正是为初学者量身定做!我们将教你大量\n有关 Rust 的知识, 但在我们开始之前,以下有几个关于如何使用 Rustlings 的说明:\n\n1. Rustl"
},
{
"path": "assets/rustlings-zh/exercises/README.md",
"chars": 980,
"preview": "# Exercise to Book Chapter mapping\n\n| Exercise | Book Chapter |\n|------------------------|--------------|\n"
},
{
"path": "assets/rustlings-zh/exercises/advanced_errors/advanced_errs1.rs",
"chars": 2613,
"preview": "// advanced_errs1.rs\n\n// Remember back in errors6, we had multiple mapping functions so that we\n// could translate lower"
},
{
"path": "assets/rustlings-zh/exercises/advanced_errors/advanced_errs2.rs",
"chars": 6555,
"preview": "// advanced_errs2.rs\n\n// This exercise demonstrates a few traits that are useful for custom error\n// types to implement,"
},
{
"path": "assets/rustlings-zh/exercises/clippy/README.md",
"chars": 381,
"preview": "# Clippy\n\nThe Clippy tool is a collection of lints to analyze your code so you can catch common mistakes and improve you"
},
{
"path": "assets/rustlings-zh/exercises/clippy/clippy1.rs",
"chars": 479,
"preview": "// clippy1.rs\n// The Clippy tool is a collection of lints to analyze your code\n// so you can catch common mistakes and i"
},
{
"path": "assets/rustlings-zh/exercises/clippy/clippy2.rs",
"chars": 233,
"preview": "// clippy2.rs\n// Make me compile! Execute `rustlings hint clippy2` for hints :)\n\n// I AM NOT DONE\n\nfn main() {\n let m"
},
{
"path": "assets/rustlings-zh/exercises/collections/README.md",
"chars": 693,
"preview": "# 集合(Collections)\n\nRust 的标准库包含了很多有用的数据结构,它们称作为集合。\n大多其它的数据类型通常仅表示一个特定的值,但集合可以包含多个值。\n内置的数组和元组类型指向的数据存储在堆上,这意味着存储的数据不必在编译时确"
},
{
"path": "assets/rustlings-zh/exercises/collections/hashmap1.rs",
"chars": 722,
"preview": "// hashmap1.rs\n\n// 用散列表定义一个水果篮。以键表示水果的名称,值来代表篮子里对应水果的个数。\n// 要求必须在篮子里放至少三种水果(如苹果、香蕉、芒果),每种水果的总数也应不少于五个。\n//\n// 让我通过编译和测试!\n"
},
{
"path": "assets/rustlings-zh/exercises/collections/hashmap2.rs",
"chars": 1728,
"preview": "// hashmap2.rs\n// 给你一个用散列表表示的水果篮,它的键表示水果的名称,值表示篮子里对应水果的个数。\n// 现在需要往篮子添加至少 11 种水果。篮子里已有 - 苹果 (4),\n// 芒果 (2) 和荔枝 (5) 三种水果,"
},
{
"path": "assets/rustlings-zh/exercises/collections/vec1.rs",
"chars": 443,
"preview": "// vec1.rs\n// 你的任务是创建一个与数组 `a` 中的元素完全相同的 `Vec`。\n// 让我通过编译和测试!\n// 如果需要提示,可以执行命令 `rustlings hint vec1`。\n\n// I AM NOT DONE\n"
},
{
"path": "assets/rustlings-zh/exercises/collections/vec2.rs",
"chars": 584,
"preview": "// vec2.rs\n// 给定一个全是偶数的 Vec 。你的任务是完成一个循环,做到将 Vec 中的每个数字都乘以 2 。\n//\n// 让我通过编译和测试!\n//\n// 如果需要提示,可以执行命令 `rustlings hint vec2"
},
{
"path": "assets/rustlings-zh/exercises/conversions/README.md",
"chars": 1586,
"preview": "# Type conversions\n\nRust offers a multitude of ways to convert a value of a given type into another type.\n\nThe simplest "
},
{
"path": "assets/rustlings-zh/exercises/conversions/as_ref_mut.rs",
"chars": 1398,
"preview": "// AsRef and AsMut allow for cheap reference-to-reference conversions.\n// Read more about them at https://doc.rust-lang."
},
{
"path": "assets/rustlings-zh/exercises/conversions/from_into.rs",
"chars": 3862,
"preview": "// The From trait is used for value-to-value conversions.\n// If From is implemented correctly for a type, the Into trait"
},
{
"path": "assets/rustlings-zh/exercises/conversions/from_str.rs",
"chars": 3336,
"preview": "// from_str.rs\n// This is similar to from_into.rs, but this time we'll implement `FromStr`\n// and return errors instead "
},
{
"path": "assets/rustlings-zh/exercises/conversions/try_from_into.rs",
"chars": 5257,
"preview": "// try_from_into.rs\n// TryFrom is a simple and safe type conversion that may fail in a controlled way under some circums"
},
{
"path": "assets/rustlings-zh/exercises/conversions/using_as.rs",
"chars": 686,
"preview": "// Type casting in Rust is done via the usage of the `as` operator.\n// Please note that the `as` operator is not only us"
},
{
"path": "assets/rustlings-zh/exercises/enums/README.md",
"chars": 362,
"preview": "# 枚举(enums)\n\nRust 有一种叫做“枚举”的类型,这种类型列举出了某种集合中所有可能的值。\n枚举是许多语言共有的一个功能,但它的作用在每种语言中都有所不同。\n如 F#、OCaml 和 Haskell 之类的函数式语言中的代数数据"
},
{
"path": "assets/rustlings-zh/exercises/enums/enums1.rs",
"chars": 317,
"preview": "// enums1.rs\n// 让我能够编译!执行 `rustex hint enums1` 获取提示 :)\n\n// I AM NOT DONE\n\n#[derive(Debug)]\nenum Message {\n // TODO:遵照"
},
{
"path": "assets/rustlings-zh/exercises/enums/enums2.rs",
"chars": 483,
"preview": "// enums2.rs\n// 让我能够编译!执行 `rustex hint enums2` 获取提示!\n\n// I AM NOT DONE\n\n#[derive(Debug)]\nenum Message {\n // TODO:定义下面"
},
{
"path": "assets/rustlings-zh/exercises/enums/enums3.rs",
"chars": 1267,
"preview": "// enums3.rs\n// 解决所有的 TODO ,通过测试!\n\n// I AM NOT DONE\n\nenum Message {\n // TODO:根据以下的使用方式,实现 Message 的不同类型\n}\n\nstruct Poi"
},
{
"path": "assets/rustlings-zh/exercises/error_handling/README.md",
"chars": 479,
"preview": "# 错误处理\n大多数的错误并没有严重到需要让程序完全停止运行的程度。\n有时一个函数执行失败时,你可以很容易地对造成失败的原因进行解释并采取对应措施的。\n例如,你正试图打开一个文件,但由于该文件不存在导致了操作失败,这时你可能想创建\n该文件而"
},
{
"path": "assets/rustlings-zh/exercises/error_handling/errors1.rs",
"chars": 997,
"preview": "// errors1.rs\n// 假使你传给这个函数一个空字符串,那么它将拒绝生成一段个性签名(nametage)。\n// 如果它能解释拒绝的原因是什么,而不是粗暴返回 `None` 那就更完美了。\n// 第 2 个测试目前还没通过并未能编"
},
{
"path": "assets/rustlings-zh/exercises/error_handling/errors2.rs",
"chars": 1048,
"preview": "// errors2.rs\n// 假设我们正在编写一个游戏,你可以用代币购买物品。\n// 所有物品的价格都是 5 个代币,每当你购买物品时,都需要 1 个代币的小费。\n// 游戏玩家将输入他们想要购买的物品数量,`total_cost` 函"
},
{
"path": "assets/rustlings-zh/exercises/error_handling/errors3.rs",
"chars": 717,
"preview": "// errors3.rs\n// 这是一个试图使用前面练习中 `total_cost` 函数完整版的程序。\n// 但出了些问题!为什么不行?我们需要怎样做才能解决问题?\n// 执行 `rustlings hint errors3` 获取提示"
},
{
"path": "assets/rustlings-zh/exercises/error_handling/errors4.rs",
"chars": 641,
"preview": "// errors4.rs\n// 通过测试!执行 `rustlings hint errors4` 获取提示 :)\n\n// I AM NOT DONE\n\n#[derive(PartialEq, Debug)]\nstruct Positive"
},
{
"path": "assets/rustlings-zh/exercises/error_handling/errors5.rs",
"chars": 1272,
"preview": "// errors5.rs\n\n// 这个程序使用练习 errors4 代码的完整版。\n// 它现在不能编译! 为什么呢?\n// 执行 `rustlings hint errors5` 获取提示!\n\n// I AM NOT DONE\n\nuse"
},
{
"path": "assets/rustlings-zh/exercises/error_handling/errors6.rs",
"chars": 2152,
"preview": "// errors6.rs\n\n// 像 `Box<dyn error::Error>` 这样的万能错误类型并不推荐用于库代码,\n// 因为调用者可能想根据错误内容进行相关处理,而不是将其打印出来或进一步传播。\n// 在这里,我们自定义了一个"
},
{
"path": "assets/rustlings-zh/exercises/functions/README.md",
"chars": 208,
"preview": "# 函数(Functions)\n\n在本练习,你将学习如何编写一个函数,以及 Rust 编译器怎样可以对事物进行追溯(trace things way back)。\n\n译:依据练习的内容,追溯的意思可能是类型推导之类的事。\n\n## 更多信息\n"
},
{
"path": "assets/rustlings-zh/exercises/functions/functions1.rs",
"chars": 157,
"preview": "// functions1.rs\n// 让我能够编译!执行 `rustex hint functions1` 获取提示 :)\n\n// I AM NOT DONE\n\n/// 翻译: [mg-chao](https://github.com/m"
},
{
"path": "assets/rustlings-zh/exercises/functions/functions2.rs",
"chars": 273,
"preview": "// functions2.rs\n// 让我能够编译!执行 `rustex hint functions2` 获取提示 :)\n\n// I AM NOT DONE\n\n/// 翻译: [mg-chao](https://github.com/m"
},
{
"path": "assets/rustlings-zh/exercises/functions/functions3.rs",
"chars": 260,
"preview": "// functions3.rs\n// 让我能够编译!执行 `rustex hint functions3` 获取提示 :)\n\n// I AM NOT DONE\n\n/// 翻译: [mg-chao](https://github.com/m"
},
{
"path": "assets/rustlings-zh/exercises/functions/functions4.rs",
"chars": 518,
"preview": "// functions4.rs\n// 让我能够编译!执行 `rustex hint functions4` 获取提示 :)\n\n// 商店正在进行促销,如果价格是偶数,可以优惠 10 Rustbucks,如果是奇数,则优惠 3 Rustbu"
},
{
"path": "assets/rustlings-zh/exercises/functions/functions5.rs",
"chars": 272,
"preview": "// functions5.rs\n// 让我能够编译!执行 `rustex hint functions5` 获取提示 :)\n\n// I AM NOT DONE\n\n/// 翻译: [mg-chao](https://github.com/m"
},
{
"path": "assets/rustlings-zh/exercises/generics/README.md",
"chars": 260,
"preview": "# 泛型\n\n泛型的主旨是把类型和函数泛化到多种情况。\n这在很多方面有助于减少重复代码,但也可能需要为此使用相当多的语法。\n也就是说,使用泛型的话则需要小心谨慎地标明泛型适用于哪些类型。\n\n## 更多信息\n\n- [Generic Data T"
},
{
"path": "assets/rustlings-zh/exercises/generics/generics1.rs",
"chars": 190,
"preview": "// 这个购物清单程序无法编译!\n// 用你对泛型的了解来解决这个问题。\n\n// 执行 `rustlings hint generics1` 获取提示!\n\n// I AM NOT DONE\n\nfn main() {\n let mut "
},
{
"path": "assets/rustlings-zh/exercises/generics/generics2.rs",
"chars": 498,
"preview": "// 这个强大的 Wrapper 拥有存储一个正整数值的能力。\n// 利用泛型重写它,使它支持包装(wrapping)任何类型的值。\n\n// 执行 `rustlings hint generics2` 获取提示!\n\n// I AM NOT "
},
{
"path": "assets/rustlings-zh/exercises/generics/generics3.rs",
"chars": 1338,
"preview": "// 一所想象的魔法学院有一个采用 Rust 编写的新版成绩单生成系统!\n// 目前该系统仅支持创建以数字表示的成绩单(如 1.0 -> 5.5)。\n// 然而,学校也发布用字母表示的成绩(A+ -> F-),所以需要能够打印两种成绩单。\n"
},
{
"path": "assets/rustlings-zh/exercises/if/README.md",
"chars": 157,
"preview": "# If\n\n你将在这学习最基本的控制流(control flow)——`if`\n\n## 更多信息\n\n- [Control Flow - if expressions](https://doc.rust-lang.org/book/ch03-"
},
{
"path": "assets/rustlings-zh/exercises/if/if1.rs",
"chars": 430,
"preview": "// if1.rs\n\n// I AM NOT DONE\n\npub fn bigger(a: i32, b: i32) -> i32 {\n // 完成这个返回更大数字的函数!\n // 但不允许以下方式:\n // - 调用其它"
},
{
"path": "assets/rustlings-zh/exercises/if/if2.rs",
"chars": 582,
"preview": "// if2.rs\n\n// 第一步:让我能够编译!\n// 第二步:bar_for_fuzz 和 default_to_baz 可以通过测试!\n// 执行 `rustex hint if2` 获取提示 :)\n\n// I AM NOT DONE"
},
{
"path": "assets/rustlings-zh/exercises/macros/README.md",
"chars": 403,
"preview": "# Macros\n\nRust's macro system is very powerful, but also kind of difficult to wrap your\nhead around. We're not going to "
},
{
"path": "assets/rustlings-zh/exercises/macros/macros1.rs",
"chars": 216,
"preview": "// macros1.rs\n// Make me compile! Execute `rustlings hint macros1` for hints :)\n\n// I AM NOT DONE\n\nmacro_rules! my_macro"
},
{
"path": "assets/rustlings-zh/exercises/macros/macros2.rs",
"chars": 217,
"preview": "// macros2.rs\n// Make me compile! Execute `rustlings hint macros2` for hints :)\n\n// I AM NOT DONE\n\nfn main() {\n my_ma"
},
{
"path": "assets/rustlings-zh/exercises/macros/macros3.rs",
"chars": 299,
"preview": "// macros3.rs\n// Make me compile, without taking the macro out of the module!\n// Execute `rustlings hint macros3` for hi"
},
{
"path": "assets/rustlings-zh/exercises/macros/macros4.rs",
"chars": 320,
"preview": "// macros4.rs\n// Make me compile! Execute `rustlings hint macros4` for hints :)\n\n// I AM NOT DONE\n\nmacro_rules! my_macro"
},
{
"path": "assets/rustlings-zh/exercises/modules/README.md",
"chars": 174,
"preview": "# 模块(Modules)\n\n这部分我们将向你介绍 Rust 的模块系统。\n\n## 更多信息\n\n- [The Module System](https://doc.rust-lang.org/book/ch07-00-managing-gr"
},
{
"path": "assets/rustlings-zh/exercises/modules/modules1.rs",
"chars": 340,
"preview": "// modules1.rs\n// 让我能够编译!执行 `rustex hint modules1` 获取提示 :)\n\n// I AM NOT DONE\n\nmod sausage_factory {\n // 确保它仅在当前模块可见。\n"
},
{
"path": "assets/rustlings-zh/exercises/modules/modules2.rs",
"chars": 665,
"preview": "// modules2.rs\n// 你可以把模块引入作用域,并使用 'use' 和 'as' 关键字给它们取个别称.\n// 修复 'use' 语句的相关代码以通过编译。\n// 让我能够编译!执行 `rustex hint modules2`"
},
{
"path": "assets/rustlings-zh/exercises/modules/modules3.rs",
"chars": 450,
"preview": "// modules3.rs\n// 你可以使用 'use' 关键字将任何位置的模块(特别是 Rust 标准库中的模块)引入作用域。\n// 从 std::time 模块引入 SystemTime 和 UNIX_EPOCH。如果你能用一行代码解"
},
{
"path": "assets/rustlings-zh/exercises/move_semantics/README.md",
"chars": 365,
"preview": "# 移动语义(Move Semantics)\n\n这些练习改编自 [pnkfelix](https://github.com/pnkfelix) 的 [Rust Tutorial](https://pnkfelix.github.io/rus"
},
{
"path": "assets/rustlings-zh/exercises/move_semantics/move_semantics1.rs",
"chars": 495,
"preview": "// move_semantics1.rs\n// 让我能够编译!执行 `rustex hint move_semantics1` 获取提示 :)\n\n// I AM NOT DONE\n\nfn main() {\n let vec0 = V"
},
{
"path": "assets/rustlings-zh/exercises/move_semantics/move_semantics2.rs",
"chars": 505,
"preview": "// move_semantics2.rs\n// 在不更改第 13 行的要求下通过编译!\n// 执行 `rustex hint move_semantics2` 获取提示 :)\n\n// I AM NOT DONE\n\nfn main() {\n"
},
{
"path": "assets/rustlings-zh/exercises/move_semantics/move_semantics3.rs",
"chars": 484,
"preview": "// move_semantics3.rs\n// 在不添加新行仅改变已有行的要求下通过编译!\n// (也不允许有多个分号的行!)\n// 执行 `rustex hint move_semantics3` 获取提示 :)\n\n// I AM NO"
},
{
"path": "assets/rustlings-zh/exercises/move_semantics/move_semantics4.rs",
"chars": 598,
"preview": "// move_semantics4.rs\n// 重构这段代码,做到删除 `vec0` ,并在 `fn fill_vec` 而非 `fn main` 中创建 vector ,\n// 然后将新创建的 vector 从 `fill_vec` 转"
},
{
"path": "assets/rustlings-zh/exercises/move_semantics/move_semantics5.rs",
"chars": 263,
"preview": "// move_semantics5.rs\n// 只通过重新排列 `main()` 中的已有行来完成编译,并且不能增加、更改或删除任何行\n// 执行 `rustex hint move_semantics5` 获取提示 :)\n\n// I A"
},
{
"path": "assets/rustlings-zh/exercises/option/README.md",
"chars": 1072,
"preview": "# Option\n\nOption 类型代表可选的值:每个 Option 要么是 Some ,包含一个值;要么是 None ,表示空值。\nOption 在 Rust 代码中十分常见,因为它有许多用途:\n- 初始值\n- 输入值不符合定义的情况下"
},
{
"path": "assets/rustlings-zh/exercises/option/option1.rs",
"chars": 467,
"preview": "// option1.rs\n// 让我通过编译!执行 `rustlings hint option1` 获取提示!\n\n// I AM NOT DONE\n\n// 你可以自由修改代码,但这个函数签名除外。\nfn print_number(may"
},
{
"path": "assets/rustlings-zh/exercises/option/option2.rs",
"chars": 692,
"preview": "// option2.rs\n// 让我通过编译!执行 `rustlings hint option2` 获取提示!\n\n// I AM NOT DONE\n\nfn main() {\n let optional_word = Some(St"
},
{
"path": "assets/rustlings-zh/exercises/option/option3.rs",
"chars": 336,
"preview": "// option3.rs\n// 让我通过编译!执行 `rustlings hint option3` 获取提示\n\n// I AM NOT DONE\n\nstruct Point {\n x: i32,\n y: i32,\n}\n\nfn"
},
{
"path": "assets/rustlings-zh/exercises/primitive_types/README.md",
"chars": 231,
"preview": "# 基本类型(Primitive Types)\n\nRust 有几个直接在编译器中实现基本类型。在本节中,我们来看看最重要的几个。\n\n## 更多信息\n\n- [Data Types](https://doc.rust-lang.org/stab"
},
{
"path": "assets/rustlings-zh/exercises/primitive_types/primitive_types1.rs",
"chars": 350,
"preview": "// primitive_types1.rs\n// 补充不完整代码行的缺失部分!\n// 没有提示,也没有什么诀窍,只要习惯于键入这些内容就可以了 :)\n\n// I AM NOT DONE\n\nfn main() {\n // Boolea"
},
{
"path": "assets/rustlings-zh/exercises/primitive_types/primitive_types2.rs",
"chars": 764,
"preview": "// primitive_types2.rs\n// 补充不完整代码行的缺失部分!\n// 没有提示,也没有什么诀窍,只要习惯于键入这些内容就可以了 :)\n\n// I AM NOT DONE\n\nfn main() {\n // Charac"
},
{
"path": "assets/rustlings-zh/exercises/primitive_types/primitive_types3.rs",
"chars": 336,
"preview": "// primitive_types3.rs\n// 在 ??? 处创建一个不少于 100 个元素的数组。\n// 执行 `rustex hint primitive_types3` 获取提示!\n\n// I AM NOT DONE\n\nfn ma"
},
{
"path": "assets/rustlings-zh/exercises/primitive_types/primitive_types4.rs",
"chars": 253,
"preview": "// primitive_types4.rs\n// 在 ??? 处获取数组 a 的一个切片(slice),以通过测试。\n// 执行 `rustex hint primitive_types4` 获取提示!!\n\n// I AM NOT DON"
},
{
"path": "assets/rustlings-zh/exercises/primitive_types/primitive_types5.rs",
"chars": 283,
"preview": "// primitive_types5.rs\n// 对 `cat` 元组进行解构(Destructure),使 println 能够运行。\n// 执行 `rustex hint primitive_types5` 获取提示!\n\n// I A"
},
{
"path": "assets/rustlings-zh/exercises/primitive_types/primitive_types6.rs",
"chars": 369,
"preview": "// primitive_types6.rs\n// 使用元组索引(tuple index)来访问 `numbers` 的第二个元素。\n// 你可以把第二个元素的表达式放在 ??? 处,这样测试就会通过。\n// 执行 `rustex hint"
},
{
"path": "assets/rustlings-zh/exercises/quiz1.rs",
"chars": 686,
"preview": "// quiz1.rs\n// This is a quiz for the following sections:\n// - Variables\n// - Functions\n\n// Mary is buying apples. One a"
},
{
"path": "assets/rustlings-zh/exercises/quiz2.rs",
"chars": 893,
"preview": "// quiz2.rs\n// This is a quiz for the following sections:\n// - Strings\n\n// Ok, here are a bunch of values-- some are `St"
},
{
"path": "assets/rustlings-zh/exercises/quiz3.rs",
"chars": 711,
"preview": "// quiz3.rs\n// This is a quiz for the following sections:\n// - Tests\n\n// This quiz isn't testing our function -- make it"
},
{
"path": "assets/rustlings-zh/exercises/quiz4.rs",
"chars": 430,
"preview": "// quiz4.rs\n// This quiz covers the sections:\n// - Modules\n// - Macros\n\n// Write a macro that passes the quiz! No hints "
},
{
"path": "assets/rustlings-zh/exercises/standard_library_types/README.md",
"chars": 448,
"preview": "# Standard library types\n\nThis section will teach you about Box, Shared-State Concurrency and Iterators.\n\n## Further inf"
},
{
"path": "assets/rustlings-zh/exercises/standard_library_types/arc1.rs",
"chars": 1698,
"preview": "// arc1.rs\n// In this exercise, we are given a Vec of u32 called \"numbers\" with values ranging\n// from 0 to 99 -- [ 0, 1"
},
{
"path": "assets/rustlings-zh/exercises/standard_library_types/box1.rs",
"chars": 1581,
"preview": "// box1.rs\n//\n// At compile time, Rust needs to know how much space a type takes up. This becomes problematic\n// for rec"
},
{
"path": "assets/rustlings-zh/exercises/standard_library_types/iterators1.rs",
"chars": 954,
"preview": "// iterators1.rs\n//\n// Make me compile by filling in the `???`s\n//\n// When performing operations on elements within a c"
},
{
"path": "assets/rustlings-zh/exercises/standard_library_types/iterators2.rs",
"chars": 1539,
"preview": "// iterators2.rs\n// In this exercise, you'll learn some of the unique advantages that iterators\n// can offer. Follow the"
},
{
"path": "assets/rustlings-zh/exercises/standard_library_types/iterators3.rs",
"chars": 2244,
"preview": "// iterators3.rs\n// This is a bigger exercise than most of the others! You can do it!\n// Here is your mission, should yo"
},
{
"path": "assets/rustlings-zh/exercises/standard_library_types/iterators4.rs",
"chars": 675,
"preview": "// iterators4.rs\n\n// I AM NOT DONE\n\npub fn factorial(num: u64) -> u64 {\n // Complete this function to return the fact"
},
{
"path": "assets/rustlings-zh/exercises/standard_library_types/iterators5.rs",
"chars": 3521,
"preview": "// iterators5.rs\n// Let's define a simple model to track Rustlings exercise progress. Progress\n// will be modelled using"
},
{
"path": "assets/rustlings-zh/exercises/strings/README.md",
"chars": 181,
"preview": "# 字符串\n\nRust 有两种字符串类型,一种是字符串切片(`&str`),另一种是拥有所有权的字符串(`String`)。我们不打算向你说明何时使用其中哪一种,但我们将为你讲解如何区分和创建它们,并灵活使用。\n\n## 更多信息\n\n- [S"
},
{
"path": "assets/rustlings-zh/exercises/strings/strings1.rs",
"chars": 297,
"preview": "// strings1.rs\n// 在不改变函数签名的要求下通过编译!\n// 执行 `rustlings hint strings1` 获取提示 ;)\n\n// I AM NOT DONE\n\nfn main() {\n let answe"
},
{
"path": "assets/rustlings-zh/exercises/strings/strings2.rs",
"chars": 466,
"preview": "// strings2.rs\n// 在不改变函数签名的要求下通过编译!\n// 执行 `rustlings hint strings2` 获取提示 ;)\n\n// I AM NOT DONE\n\nfn main() {\n let word "
},
{
"path": "assets/rustlings-zh/exercises/structs/README.md",
"chars": 212,
"preview": "# 结构(Structs)\n\nRust 有三种结构类型:经典的 C 结构、元组结构和单元结构。\n\n## 更多信息\n\n- [Structures](https://doc.rust-lang.org/book/ch05-01-defining"
},
{
"path": "assets/rustlings-zh/exercises/structs/structs1.rs",
"chars": 818,
"preview": "// structs1.rs\n// 解决所有的 TODO ,通过测试!\n\n// I AM NOT DONE\n\nstruct ColorClassicStruct {\n // TODO: 一些东西需要在这里\n}\n\nstruct Colo"
},
{
"path": "assets/rustlings-zh/exercises/structs/structs2.rs",
"chars": 1171,
"preview": "// structs2.rs\n// 解决所有的 TODO ,通过测试!\n\n// I AM NOT DONE\n\n#[derive(Debug)]\nstruct Order {\n name: String,\n year: u32,\n"
},
{
"path": "assets/rustlings-zh/exercises/structs/structs3.rs",
"chars": 2132,
"preview": "// structs3.rs\n// 接口既可以包含数据也可以处理逻辑。\n// 在这个练习中,我们已经定义了 Package 结构,但我们想测试一些根据它实现的逻辑。\n// 让代码通过编译和测试!\n// 如果你有问题,可以执行 `rustli"
},
{
"path": "assets/rustlings-zh/exercises/tests/README.md",
"chars": 128,
"preview": "# 测试\n\n这次不按书本上的顺序介绍测试——接下来的很多练习都会要求你通过测试!\n\n## 更多信息\n\n- [Writing Tests](https://doc.rust-lang.org/book/ch11-01-writing-test"
},
{
"path": "assets/rustlings-zh/exercises/tests/tests1.rs",
"chars": 271,
"preview": "// tests1.rs\n// 测试对于确保代码实现了预期功能非常重要。\n// 可以用下面的命令对当前文件中的代码进行测试:\n// rustlings run tests1\n\n// 关于测试还有个问题——如何成功编译测试、通过测试或者使测试"
},
{
"path": "assets/rustlings-zh/exercises/tests/tests2.rs",
"chars": 190,
"preview": "// tests2.rs\n// 让测试能够编译然后通过测试和使测试失败!\n// 执行 `rustlings hint tests2` 获取提示 :)\n\n// I AM NOT DONE\n\n#[cfg(test)]\nmod tests {\n "
},
{
"path": "assets/rustlings-zh/exercises/tests/tests3.rs",
"chars": 407,
"preview": "// tests3.rs\n// 这个测试不是在测试我们的函数——想些方法让它的返回值可以通过测试。\n// 在第二个测试判断调用 `is_even(5)` 是否得到了预期的结果。\n// 执行 `rustlings hint tests3` 获"
},
{
"path": "assets/rustlings-zh/exercises/threads/README.md",
"chars": 521,
"preview": "# Threads\n\nIn most current operating systems, an executed program’s code is run in a process, and the operating system m"
},
{
"path": "assets/rustlings-zh/exercises/threads/threads1.rs",
"chars": 990,
"preview": "// threads1.rs\n// Make this compile! Execute `rustlings hint threads1` for hints :)\n// The idea is the thread spawned on"
},
{
"path": "assets/rustlings-zh/exercises/traits/README.md",
"chars": 406,
"preview": "# Traits\n\nTrait 是一系列方法的集合。\n\n数据类型可以实现 trait。为此需要帮数据类型定义好构成 trait 的方法。 \n例如,`String` 类型实现了 `From<&str>` trait。它赋予我们能力写出 `St"
},
{
"path": "assets/rustlings-zh/exercises/traits/traits1.rs",
"chars": 718,
"preview": "// traits1.rs\n// 是时候来实现些 trait 了!\n//\n// 你的任务是为 `String` 实现 `AppendBar` trait。\n//\n// `AppendBar` 只有一个函数,它将 \"Bar\" 追加到任何实现该"
},
{
"path": "assets/rustlings-zh/exercises/traits/traits2.rs",
"chars": 501,
"preview": "// traits2.rs\n//\n// 你的任务是为一个字符串 vector 实现 `AppendBar` trait。\n//\n// 为了实现该 trait,请思考下将 \"Bar\" 追加到字符串 vector 的意义是什么? \n//\n// "
},
{
"path": "assets/rustlings-zh/exercises/variables/README.md",
"chars": 209,
"preview": "# 变量(Variables)\n\n在 Rust,变量默认是不可变的.\n不可变意味着当一个值被绑定到某个名字上,你就不能再对这个值做出更改。\n当然,你可以通过在变量名前添加 mut 来使它们变得可变。\n\n## 更多信息\n\n- [Variabl"
},
{
"path": "assets/rustlings-zh/exercises/variables/variables1.rs",
"chars": 334,
"preview": "// variables1.rs\n// 让我能够编译!执行 `rustex hint variables1` 获取提示 :)\n\n// 关于 `I AM NOT DONE`:\n// 即使你已经想到了解决方案,我们有时也会鼓励你在特定的练习\n/"
},
{
"path": "assets/rustlings-zh/exercises/variables/variables2.rs",
"chars": 261,
"preview": "// variables2.rs\n// 让我能够编译!执行 `rustex hint variables2` 获取提示 :)\n\n// I AM NOT DONE\n\n/// 翻译: [mg-chao](https://github.com/m"
},
{
"path": "assets/rustlings-zh/exercises/variables/variables3.rs",
"chars": 277,
"preview": "// variables3.rs\n// 让我能够编译!执行 `rustex hint variables3` 获取提示 :)\n\n// I AM NOT DONE\n\n/// 翻译: [mg-chao](https://github.com/m"
},
{
"path": "assets/rustlings-zh/exercises/variables/variables4.rs",
"chars": 188,
"preview": "// variables4.rs\n// 让我能够编译!执行 `rustex hint variables4` 获取提示 :)\n\n// I AM NOT DONE\n\n/// 翻译: [mg-chao](https://github.com/m"
},
{
"path": "assets/rustlings-zh/exercises/variables/variables5.rs",
"chars": 343,
"preview": "// variables5.rs\n// 让我能够编译!执行 `rustex hint variables5` 获取提示 :)\n\n// I AM NOT DONE\n\n/// 翻译: [mg-chao](https://github.com/m"
},
{
"path": "assets/rustlings-zh/exercises/variables/variables6.rs",
"chars": 195,
"preview": "// variables6.rs\n// 让我能够编译!执行 `rustex hint variables6` 获取提示 :)\n\n// I AM NOT DONE\n\n/// 翻译: [mg-chao](https://github.com/m"
},
{
"path": "assets/rustlings-zh/info.toml",
"chars": 28261,
"preview": "# VARIABLES\n\n[[exercises]]\nname = \"variables1\"\npath = \"exercises/variables/variables1.rs\"\nmode = \"compile\"\nhint = \"\"\"\n提示"
},
{
"path": "assets/rustlings-zh/install.ps1",
"chars": 3022,
"preview": "#!/usr/bin/env pwsh\n\n#Requires -Version 5\nparam($path = \"$pwd/rustlings\")\n\nWrite-Host \"Let's get you set up with Rustlin"
},
{
"path": "assets/rustlings-zh/install.sh",
"chars": 3787,
"preview": "#!/usr/bin/env bash\n\necho \"Let's get you set up with Rustlings!\"\n\necho \"Checking requirements...\"\nif [ -x \"$(command -v "
},
{
"path": "assets/rustlings-zh/src/exercise.rs",
"chars": 10953,
"preview": "use regex::Regex;\nuse serde::Deserialize;\nuse std::env;\nuse std::fmt::{self, Display, Formatter};\nuse std::fs::{self, re"
},
{
"path": "assets/rustlings-zh/src/main.rs",
"chars": 15443,
"preview": "use crate::exercise::{Exercise, ExerciseList};\nuse crate::run::run;\nuse crate::verify::verify;\nuse argh::FromArgs;\nuse c"
},
{
"path": "assets/rustlings-zh/src/run.rs",
"chars": 1930,
"preview": "use crate::exercise::{Exercise, Mode};\nuse crate::verify::test;\nuse indicatif::ProgressBar;\n\n// Invoke the rust compiler"
},
{
"path": "assets/rustlings-zh/src/ui.rs",
"chars": 928,
"preview": "macro_rules! warn {\n ($fmt:literal, $ex:expr) => {{\n use console::{style, Emoji};\n use std::env;\n "
},
{
"path": "assets/rustlings-zh/src/verify.rs",
"chars": 6114,
"preview": "use crate::exercise::{CompiledExercise, Exercise, Mode, State};\nuse console::style;\nuse indicatif::ProgressBar;\nuse std:"
},
{
"path": "assets/rustlings-zh/tests/fixture/failure/compFailure.rs",
"chars": 21,
"preview": "fn main() {\n let\n}"
},
{
"path": "assets/rustlings-zh/tests/fixture/failure/compNoExercise.rs",
"chars": 14,
"preview": "fn main() {\n}\n"
},
{
"path": "assets/rustlings-zh/tests/fixture/failure/info.toml",
"chars": 176,
"preview": "[[exercises]]\nname = \"compFailure\"\npath = \"compFailure.rs\"\nmode = \"compile\"\nhint = \"\"\n\n[[exercises]]\nname = \"testFailure"
},
{
"path": "assets/rustlings-zh/tests/fixture/failure/testFailure.rs",
"chars": 43,
"preview": "#[test]\nfn passing() {\n asset!(true);\n}\n"
},
{
"path": "assets/rustlings-zh/tests/fixture/failure/testNotPassed.rs",
"chars": 49,
"preview": "#[test]\nfn not_passing() {\n assert!(false);\n}\n"
},
{
"path": "assets/rustlings-zh/tests/fixture/state/finished_exercise.rs",
"chars": 33,
"preview": "// fake_exercise\n\nfn main() {\n\n}\n"
},
{
"path": "assets/rustlings-zh/tests/fixture/state/info.toml",
"chars": 312,
"preview": "[[exercises]]\nname = \"pending_exercise\"\npath = \"pending_exercise.rs\"\nmode = \"compile\"\nhint = \"\"\"\"\"\"\n\n[[exercises]]\nname "
},
{
"path": "assets/rustlings-zh/tests/fixture/state/pending_exercise.rs",
"chars": 51,
"preview": "// fake_exercise\n\n// I AM NOT DONE\n\nfn main() {\n\n}\n"
},
{
"path": "assets/rustlings-zh/tests/fixture/state/pending_test_exercise.rs",
"chars": 43,
"preview": "// I AM NOT DONE\n\n#[test]\nfn it_works() {}\n"
},
{
"path": "assets/rustlings-zh/tests/fixture/success/compSuccess.rs",
"chars": 14,
"preview": "fn main() {\n}\n"
},
{
"path": "assets/rustlings-zh/tests/fixture/success/info.toml",
"chars": 178,
"preview": "[[exercises]]\nname = \"compSuccess\"\npath = \"compSuccess.rs\"\nmode = \"compile\"\nhint = \"\"\"\"\"\"\n\n[[exercises]]\nname = \"testSuc"
},
{
"path": "assets/rustlings-zh/tests/fixture/success/testSuccess.rs",
"chars": 86,
"preview": "#[test]\nfn passing() {\n println!(\"THIS TEST TOO SHALL PASS\");\n assert!(true);\n}\n"
},
{
"path": "assets/rustlings-zh/tests/integration_tests.rs",
"chars": 5817,
"preview": "use assert_cmd::prelude::*;\nuse glob::glob;\nuse predicates::boolean::PredicateBooleanExt;\nuse std::fs::File;\nuse std::io"
},
{
"path": "assets/sitemap.xml",
"chars": 30812,
"preview": "<?xml version='1.0' encoding='UTF-8'?>\n<urlset>\n<url>\n<loc><![CDATA[http://course.rs]]></loc>\n<lastmod>2021-12-30</last"
},
{
"path": "assets/writing-material/books.md",
"chars": 1189,
"preview": "## 本书参考的书籍\n\n1. [Rust语言](https://doc.rust-lang.org/book)\n\n3. [Cargo教学](https://doc.rust-lang.org/cargo/index.html)\n\n4. [R"
},
{
"path": "assets/writing-material/courses.md",
"chars": 110,
"preview": "## 可借鉴的课程形式\nhttps://www.reddit.com/r/rust/comments/rwp8mo/teaching_rust_at_the_university_of_warsaw/\n\n## 练习题\n\n"
},
{
"path": "assets/writing-material/demos_for_learning.md",
"chars": 90,
"preview": "整理几个可以作为学习demo的项目,需要将注释和相关文档翻译成中文\n\n1. [mini-redis](https://github.com/tokio-rs/mini-redis)"
},
{
"path": "assets/writing-material/good-sourcecode.md",
"chars": 174,
"preview": "# 值得学习的源代码\n\nhttps://www.reddit.com/r/rust/comments/rxfx85/good_rust_source_code/\n\nhttps://www.reddit.com/r/rust/comments"
},
{
"path": "assets/writing-material/posts/Iterator.md",
"chars": 1938,
"preview": "包含了一些Iterator的常用处理方法\n## 遍历同时获取元素的索引\n```rust\n let mut xs = vec![1i32, 2, 3];\n for (i, x) in xs.iter().enumerate() {"
},
{
"path": "assets/writing-material/posts/SIMD.md",
"chars": 93,
"preview": "\nhttps://www.reddit.com/r/rust/comments/rqgwaz/why_is_my_simd_code_slower_than_the_naive_one/"
},
{
"path": "assets/writing-material/posts/atomic.md",
"chars": 70,
"preview": "https://www.reddit.com/r/rust/comments/rtqrx4/introducing_atomicstory/"
},
{
"path": "assets/writing-material/posts/attributes.md",
"chars": 218,
"preview": "## #[derive(Default)]\n```rust\n#[derive(Default)]\nstruct NotSend(Rc<()>);\n\nfn require_send(_: impl Send) {}\n\nasync fn bar"
},
{
"path": "assets/writing-material/posts/fight-with-compiler-check/borrow.md",
"chars": 534,
"preview": "## 可以通过move struct中的字段,来解决borrow和mut borrow无法共存的问题\n\n```rust\nstruct Foo {\n bar: Bar\n}\n\nlet bar: &Bar = &foo.bar;\nlet f"
},
{
"path": "assets/writing-material/posts/fight-with-compiler-check/generic.md",
"chars": 1458,
"preview": "## the type parameter `T` is not constrained by the impl trait\n\n```rust\nuse std::default::Default;\n\ntrait Maker {\n ty"
},
{
"path": "assets/writing-material/posts/file.md",
"chars": 4205,
"preview": "## 读取全部内容\n\n```rust\nuse std::fs::File;\nuse std::io::prelude::*;\nuse std::path::Path;\n\nfn main() {\n // Create a path to"
},
{
"path": "assets/writing-material/posts/function_signature.md",
"chars": 423,
"preview": "## 函数的入参是一个async function\n因为我们使用了trait bound,所以不能用`Fn() -> impl Future<Output=Result<Return, sql::Error>>`的方式.\n\n```rust\n"
},
{
"path": "assets/writing-material/posts/generics.md",
"chars": 78,
"preview": "https://stackoverflow.com/questions/37606035/pass-generic-function-as-argument"
},
{
"path": "assets/writing-material/posts/hashmap.md",
"chars": 420,
"preview": "## Key of hashmap\nAny type that implements the Eq and Hash traits can be a key in HashMap.\n\nNote that f32 and f64 do not"
},
{
"path": "assets/writing-material/posts/identifier.md",
"chars": 422,
"preview": "## Raw identifiers\nRust因为版本更迭原因,可能会新增一些`关键字`,这些新增关键字可能会导致旧的函数名调用不再通过编译,例如在Rust Edition 2015中,引入了新的关键字`try`.\n\n运行以下代码:\n```"
},
{
"path": "assets/writing-material/posts/images.md",
"chars": 110,
"preview": "## 容器类型说明图\nhttps://docs.google.com/presentation/d/1q-c7UAyrUlM-eZyTo1pd8SZ0qwA_wYxmPZVOQkoDmH4/edit#slide=id.p"
},
{
"path": "assets/writing-material/posts/interview.md",
"chars": 80,
"preview": "https://www.reddit.com/r/rust/comments/si0j6v/im_preparing_for_a_rust_interview/"
},
{
"path": "assets/writing-material/posts/io.md",
"chars": 321,
"preview": "\n## Reading input as Raw Bytes\nThe built-in String type uses UTF-8 internally, which adds a small, but nonzero overhead "
},
{
"path": "assets/writing-material/posts/lifetime.md",
"chars": 179,
"preview": "## for<'a>\n\nhttps://www.reddit.com/r/rust/comments/rq43c6/generic_fn_impl_for_iterating_over_mut_items_twice/\n\nhttps://w"
},
{
"path": "assets/writing-material/posts/lifetime_elision_rules.md",
"chars": 891,
"preview": "一些lifetime消除规则\n\n\n### 1\nLet's talk about a feature that's available in both editions: we've added some additional elision"
},
{
"path": "assets/writing-material/posts/non-lexical-lifetime.md",
"chars": 77,
"preview": "https://stackoverflow.com/questions/50251487/what-are-non-lexical-lifetimes\n\n"
},
{
"path": "assets/writing-material/posts/operators.md",
"chars": 10109,
"preview": "## Operators and Symbols\n\nThis appendix contains a glossary of Rust’s syntax, including operators and\nother symbols that"
},
{
"path": "assets/writing-material/posts/package.md",
"chars": 594,
"preview": "## layout\n```go\n.\n├── Cargo.lock\n├── Cargo.toml\n├── src/\n│ ├── lib.rs\n│ ├── main.rs\n│ └── bin/\n│ ├── named-e"
},
{
"path": "assets/writing-material/posts/performance.md",
"chars": 574,
"preview": "## books\n1. [Rust性能之书](https://nnethercote.github.io/perf-book/title-page.html)\n2. [How to write fast rust code](https:/"
},
{
"path": "assets/writing-material/posts/plugins.md",
"chars": 83,
"preview": "\nhttps://www.reddit.com/r/rust/comments/sboyb2/designing_a_rust_rust_plugin_system/"
},
{
"path": "assets/writing-material/posts/reference.md",
"chars": 826,
"preview": "## struct中的一个字段是另外一个字段的指针\n```rust\n#[derive(Debug)]\nstruct Test {\n a: String,\n b: *const String,\n}\n\nimpl Test {\n "
},
{
"path": "assets/writing-material/posts/rust-analyser.md",
"chars": 225,
"preview": "## 可以为rust-analyzer指定一个check文件夹,避免构建的cache被lock住\n\nYou can already setup rust-analyzer to use different folder. I set `Ch"
},
{
"path": "assets/writing-material/posts/self-referential.md",
"chars": 350,
"preview": "## code snippets\n1. https://stackoverflow.com/questions/67823680/open-a-single-file-from-a-zip-archive-and-pass-on-as-re"
},
{
"path": "assets/writing-material/posts/string.md",
"chars": 2712,
"preview": "## 字符串常量\n\n```rust\nfn main() {\n // You can use escapes to write bytes by their hexadecimal values...\n let byte_esca"
},
{
"path": "assets/writing-material/posts/system_command.md",
"chars": 2307,
"preview": "关于调用os的命令\n\n```rust\nuse std::process::Command;\n\nfn main() {\n let output = Command::new(\"rustc\")\n .arg(\"--versn\""
},
{
"path": "assets/writing-material/posts/tests/doc_test.md",
"chars": 2322,
"preview": "## Documentation testing\nThe primary way of documenting a Rust project is through annotating the source code. Documentat"
},
{
"path": "assets/writing-material/posts/tests/integration_test.md",
"chars": 314,
"preview": "Cargo looks for integration tests in `tests` directory next to `src`.\n\nFile `src/lib.rs`:\n\n```rust\n// Define this in a c"
},
{
"path": "assets/writing-material/posts/tests/misc.md",
"chars": 762,
"preview": "## Development dependencies\nSometimes there is a need to have dependencies for tests (or examples, or benchmarks) only. "
},
{
"path": "assets/writing-material/posts/tests/unit_test.md",
"chars": 1962,
"preview": "## Tests and ?\nin Rust 2018, your unit tests can return Result<()>, which lets you use ? in them! This can make them muc"
},
{
"path": "assets/writing-material/posts/threads.md",
"chars": 759,
"preview": "## Arc和Mutex结合实现多线程数据修改和汇总\n```rust\nuse std::sync::{Arc,Mutex};\nuse std::thread;\nuse std::time::Duration;\n\nstruct JobStat"
},
{
"path": "assets/writing-material/posts/to_resolved.md",
"chars": 185,
"preview": "## unknown `into` behavior\n\n```rust\n let s: Box<dyn Error + Send + Sync> = \"connection reset by peer\".into();\n ```\n\nthis"
},
{
"path": "assets/writing-material/posts/tokio.md",
"chars": 93,
"preview": "## 性能\n\nhttps://www.reddit.com/r/rust/comments/lg0a7b/benchmarking_tokio_tasks_and_goroutines/"
},
{
"path": "assets/writing-material/posts/trivia.md",
"chars": 107,
"preview": "## Rust冷知识\n\nhttps://www.reddit.com/r/rust/comments/rwufz4/borrow_checker_allows_borrow_of_mutably_borrowed/"
},
{
"path": "assets/writing-material/posts/wasm.md",
"chars": 92,
"preview": "https://www.reddit.com/r/rust/comments/s9yugv/compile_rust_to_wasm_and_import_as_typescript/"
},
{
"path": "assets/writing-material/style_guide/coding.md",
"chars": 754,
"preview": "# 代码风格\n\n## 使用[tap](https://github.com/myrrlyn/tap)库来实现`point-free`编程风格\n```rust\nuse tap::{Tap, TapFallible};\n\ntype SomeVa"
},
{
"path": "assets/writing-material/style_guide/naming.md",
"chars": 9721,
"preview": "# 命名规范\n\n基本的Rust命名规范在[RFC 430]中有描述.\n\n通常,对于\"type-level\"的构造Rust倾向于使用驼峰命名,而对于'value-level'的构造使用蛇形命名。详情如下:\n\n| 条目 | 惯例 |\n| ---"
},
{
"path": "assets/writing-material/读者疑惑的点记录.md",
"chars": 76,
"preview": "# 读者疑惑的点\n这里记录一些读者反馈的在阅读过程中,可能会导致疑惑或者困惑的点,后续针对这些地方,可以进行相应的内容优化。\n\n1. 引用和切片的区别\n"
},
{
"path": "book.toml",
"chars": 509,
"preview": "[rust]\nedition = \"2021\" #在线运行用2021版本的\n\n[book]\nauthors = [\"sunface\"]\nlanguage = \"zh-CN\"\ntitle = \"Rust语言圣经(Rust Course)\""
},
{
"path": "ci/copy-assets.sh",
"chars": 105,
"preview": "#!/usr/bin/env bash\n\ncp ./assets/CNAME ./book/\ncp ./assets/*.html ./book/\ncp ./assets/sitemap.xml ./book/"
},
{
"path": "deploy.sh",
"chars": 509,
"preview": "## this script deploys the static website of course.rs to github pages\n\n## build static website for book\nmdbook build\n##"
},
{
"path": "genpdf.sh",
"chars": 822,
"preview": "#! /bin/sh\n\n###########################################################\n# Description:\n# This script write for mdbook "
},
{
"path": "src/SUMMARY.md",
"chars": 16703,
"preview": "# Rust 语言圣经\n\n[关于本书](about-book.md)\n[进入 Rust 编程世界](into-rust.md)\n[避免从入门到放弃](first-try/sth-you-should-not-do.md)\n<!-- [快速查"
},
{
"path": "src/about-book.md",
"chars": 3159,
"preview": "<img src=\"https://github.com/sunface/rust-course/blob/main/assets/banner.jpg?raw=true\" />\n\nRust 语言真的好:连续八年成为全世界最受欢迎的语言、没"
},
{
"path": "src/advance/async/async-await.md",
"chars": 5968,
"preview": "# async/await 和 Stream 流处理\n\n在入门章节中,我们简单学习了该如何使用 `async/.await`, 同时在后面也了解了一些底层原理,现在是时候继续深入了。\n\n`async/.await` 是 Rust 语法的一部"
},
{
"path": "src/advance/async/future-excuting.md",
"chars": 14548,
"preview": "# 底层探秘: Future 执行器与任务调度\n\n异步编程背后到底藏有什么秘密?究竟是哪只幕后之手在操纵这一切?如果你对这些感兴趣,就继续看下去,否则可以直接跳过,因为本章节的内容对于一个 API 工程师并没有太多帮助。\n\n但是如果你希望能"
},
{
"path": "src/advance/async/getting-started.md",
"chars": 11957,
"preview": "# Async 编程简介\n\n众所周知,Rust 可以让我们写出性能高且安全的软件,那么异步编程这块儿呢?是否依然在高性能的同时保证了安全?\n\n我们先通过一张 web 框架性能对比图来感受下 Rust 异步编程的性能:\n\n<img alt=\""
},
{
"path": "src/advance/async/intro.md",
"chars": 322,
"preview": "# 异步编程\n\n在艰难的学完 Rust 入门和进阶所有的 70 个章节后,我们终于来到了这里。假如之前攀登的是珠穆朗玛峰,那么现在攀登的就是乔戈里峰( 比珠峰还难攀爬... )。\n\n如果你想开发 Web 服务器、数据库驱动、消息服务等需要高"
},
{
"path": "src/advance/async/multi-futures-simultaneous.md",
"chars": 8321,
"preview": "# 使用 `join!` 和 `select!` 同时运行多个 Future\n\n招数单一,杀伤力惊人,说的就是 `.await` ,但是光用它,还真做不到一招鲜吃遍天。比如我们该如何同时运行多个任务,而不是使用 `.await` 慢悠悠地排"
},
{
"path": "src/advance/async/pain-points-and-workarounds.md",
"chars": 5475,
"preview": "# 一些疑难问题的解决办法\n\n`async` 在 Rust 依然比较新,疑难杂症少不了,而它们往往还处于活跃开发状态,短时间内无法被解决,因此才有了本文。下面一起来看看这些问题以及相应的临时解决方案。\n\n## 在 async 语句块中使用 "
},
{
"path": "src/advance/async/pin-unpin.md",
"chars": 12348,
"preview": "# 定海神针 Pin 和 Unpin\n\n在 Rust 异步编程中,有一个定海神针般的存在,它就是 `Pin`,作用说简单也简单,说复杂也非常复杂,当初刚出来时就连一些 Rust 大佬都一头雾水,何况瑟瑟发抖的我。好在今非昔比,目前网上的资料"
},
{
"path": "src/advance/async/web-server.md",
"chars": 9050,
"preview": "# 一个实践项目: Web 服务器\n\n知识学得再多,不实际应用也是纸上谈兵,不是忘掉就是废掉,对于技术学习尤为如此。在之前章节中,我们已经学习了 `Async Rust` 的方方面面,现在来将这些知识融会贯通,最终实现一个并发 Web 服务"
},
{
"path": "src/advance/circle-self-ref/circle-reference.md",
"chars": 8392,
"preview": "# Weak 与循环引用\n\nRust 的安全性是众所周知的,但是不代表它不会内存泄漏。一个典型的例子就是同时使用 `Rc<T>` 和 `RefCell<T>` 创建循环引用,最终这些引用的计数都无法被归零,因此 `Rc<T>` 拥有的值也不"
}
]
// ... and 335 more files (download for full content)
About this extraction
This page contains the full source code of the sunface/rust-course GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 535 files (1.8 MB), approximately 762.7k tokens, and a symbol index with 393 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.