Below you will find pages that utilize the taxonomy term “Rust”
August 10, 2024
Rust学习教程清单
"\u003cp\u003e今年又一次重新学习RUST这门编程语言,并从零开发了一个kv存储系统 \u003ca href=\"https://github.com/cfanbo/minkv\"\u003eminKV\u003c/a\u003e,慢慢的越来越有感觉了。\u003c/p\u003e\n\u003cp\u003e本篇主要将日常学习中收集的一些入门教程进行一下汇总,希望对于一些想学习这门开发语言的同学有所帮助。\u003c/p\u003e\n\u003cp\u003e下面教程按照推荐顺序,由浅到深依次列出。以下内容将不定期的更新,请自行收藏。 如果您有更多好的教程的话,也可以在评论区列出,大家相互学习。\u003c/p\u003e\n\u003ch1 id=\"入门教程\"\u003e入门教程\u003c/h1\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca href=\"https://doc.rust-lang.org/book/\"\u003eRust 程序设计语言 https://doc.rust-lang.org/book/\u003c/a\u003e / (\u003ca href=\"https://kaisery.github.io/trpl-zh-cn/\"\u003e中文版\u003c/a\u003e)\u003c/p\u003e\n\u003cp\u003e官方教程,强烈推荐,同时还有非官方翻译的中文版。遗憾的是这个教程有许多概念介绍的都有点不清不楚,只能通过下方的一些资料自行补习。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca href=\"https://play.rust-lang.org/\"\u003ehttps://play.rust-lang.org/\u003c/a\u003e 在线 RUST 程序 Playground,类似golang的 Playground,非常的方便\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca href=\"https://cheats.rs/#data-layout\"\u003eRust Language Cheat Sheet\u003c/a\u003e 看完官方的教程后,紧接着就看这篇,先了解一些内存布局,后面再看其它教程就更容易理解了\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca href=\"https://doc.rust-lang.org/cargo/index.html#the-cargo-book\"\u003eThe Cargo Book\u003c/a\u003e Cargo 是RUST 中的包管理工具, …\u003c/p\u003e\u003c/li\u003e\u003c/ol\u003e"
August 10, 2024
在rust中实现自定义错误
"\u003cp\u003e\u003ca href=\"https://blog.haohtml.com/posts/error-hanlding-unwrap-and-expect-in-rust/#google_vignette\"\u003e上一篇\u003c/a\u003e 我们介绍了一些错误处理的最基本的用法,主要是指对 \u003ccode\u003epanic!\u003c/code\u003e 、\u003ccode\u003eunwrap\u003c/code\u003e、\u003ccode\u003eexpect\u003c/code\u003e 和 \u003ccode\u003e?\u003c/code\u003e 这些宏或函数的介绍。但这仅仅是一些最基本的处理方法,对于自定义错误这一块并没有做任何介绍。\u003c/p\u003e\n\u003cp\u003e实际开发中可能默认的错误类型,并无法满足我们的业务需求,这时一般需要通过定义自己的错误类型来实现。在rust中错误类型是通过 \u003ccode\u003eenum\u003c/code\u003e 枚举定义的,对此官方文档也做了一些简介,本文主要介绍一些业务开发过程中对错误的处理方案,当然主要是一些最基本的用法。\u003c/p\u003e\n\u003ch1 id=\"自定义-error\"\u003e自定义 Error\u003c/h1\u003e\n\u003cp\u003e在 Rust 中,自定义错误类型是一种常见的类型,特别是当你需要提供比标准错误类型更具体的错误信息时。Rust 中的错误处理是通过 \u003ccode\u003eResult\u003c/code\u003e 和 \u003ccode\u003eError\u003c/code\u003e trait 来实现的。以下是如何实现一个自定义错误的示例:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e定义一个错误枚举类型。\u003c/li\u003e\n\u003cli\u003e实现 \u003ccode\u003estd::fmt::Display\u003c/code\u003e 为自定义错误提供用户友好的错误信息。\u003c/li\u003e\n\u003cli\u003e实现 \u003ccode\u003estd::error::Error\u003c/code\u003e trait,这通常是通过派生 \u003ccode\u003eError\u003c/code\u003e trait 来完成的。\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e下面是一个简单的示例:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-rust\" data-lang=\"rust\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#66d9ef\"\u003euse\u003c/span\u003e std::fmt;\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#66d9ef\"\u003euse …\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e"
July 27, 2024
一款管理 .gitignore 的CLI工具- gitig
"\u003cp\u003e\u003ccode\u003egitig\u003c/code\u003e 是一款基于 \u003ca href=\"https://github.com/github/gitgnore\"\u003ehttps://github.com/github/gitgnore\u003c/a\u003e 仓库开发的\u003ccode\u003e.gitignore\u003c/code\u003e 客户端CLI 管理工具,也是每个开发者必不可少的提高工作效率的必具工具。\u003c/p\u003e\n\u003cp\u003e它基于官方仓库 \u003ca href=\"https://github.com/github/gitgnore\"\u003ehttps://github.com/github/gitgnore\u003c/a\u003e 丰富的 \u003ccode\u003e.gitignore\u003c/code\u003e 数据源,帮助开发者快速实现添加各类开发项目的git版本控制忽略文件清单。\u003c/p\u003e\n\u003ch1 id=\"开发背景\"\u003e开发背景\u003c/h1\u003e\n\u003cp\u003e工作中,经常需要开发各类项目,如基于 vscode 编写 rust 项目,这时为了方便进行Git管理控制,有些项目文件可能并不需要提交到git仓库,需要将一些文件写入 \u003ccode\u003e.gitignore\u003c/code\u003e 文件进行忽略。\u003c/p\u003e\n\u003cp\u003e如果手动编辑 \u003ccode\u003e.gitignore\u003c/code\u003e文件可能有些麻烦,另外也能会有一些文件项被遗忘或写错,这时如果有一些工具可以将行业能用的忽略配置项一键写入 \u003ccode\u003e.gitignore\u003c/code\u003e 文件似乎是一个不错的主意。\u003c/p\u003e\n\u003cp\u003e其中著名的 \u003ca href=\"https://github.com/github/gitignore\"\u003ehttps://github.com/github/gitignore\u003c/a\u003e 就是一个专门收集各类开发语句或IDE 需要忽略的 \u003ccode\u003e.gitignore\u003c/code\u003e 推荐配置的仓库,目前star …\u003c/p\u003e"
July 15, 2024
Rust 中常见的几种错误处理方法
"\u003cp\u003eRust 中错误可分为两大类:\u003cstrong\u003e可恢复的\u003c/strong\u003e(\u003cem\u003erecoverable\u003c/em\u003e)和 \u003cstrong\u003e不可恢复的\u003c/strong\u003e(\u003cem\u003eunrecoverable\u003c/em\u003e)错误。\u003c/p\u003e\n\u003cp\u003e对于一个可恢复的错误,比如文件未找到或权限不足的错误,我们很可能只想向用户报告问题,让用户来决定后续操作。\u003c/p\u003e\n\u003cp\u003e不可恢复的错误总是 bug 出现的征兆,比如试图访问一个超过数组末端的位置,因此我们要立即停止程序,主要通过 \u003ccode\u003epanic!\u003c/code\u003e 实现。\u003c/p\u003e\n\u003ch1 id=\"panic\"\u003epanic!\u003c/h1\u003e\n\u003cp\u003e\u003ccode\u003epanic!\u003c/code\u003e属于不可恢复错误类型,一旦发生程序将立即退出。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-rust\" data-lang=\"rust\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#66d9ef\"\u003efn\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003emain\u003c/span\u003e() {\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e \u003cspan style=\"color:#a6e22e\"\u003epanic!\u003c/span\u003e(\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;crash and burn\u0026#34;\u003c/span\u003e);\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e}\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e这里由用户调用 \u003ccode\u003epanic!\u003c/code\u003e 宏来实现程序的中止,同时自定义错误信息。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-shell\" data-lang=\"shell\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e➜ cargo run\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e Compiling hello-world v0.1.0 \u003cspan style=\"color:#f92672\"\u003e(\u003c/span\u003e/Users/sxf/workspace/rust/hello-world\u003cspan style=\"color:#f92672\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e Finished \u003cspan style=\"color:#e6db74\"\u003e`\u003c/span\u003edev\u003cspan style=\"color:#e6db74\"\u003e`\u003c/span\u003e profile \u003cspan style=\"color:#f92672\"\u003e[\u003c/span\u003eunoptimized + debuginfo\u003cspan style=\"color:#f92672\"\u003e]\u003c/span\u003e target\u003cspan style=\"color:#f92672\"\u003e(\u003c/span\u003es\u003cspan style=\"color:#f92672\"\u003e)\u003c/span\u003e in 0.68s\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e Running \u003cspan style=\"color:#e6db74\"\u003e`\u003c/span\u003etarget/debug/hello-world\u003cspan style=\"color:#e6db74\"\u003e` …\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e"
July 10, 2024
在Rust中如何调用一个模块或方法
"\u003cp\u003e在 Rust 中有 \u003ccode\u003e包\u003c/code\u003e、\u003ccode\u003ecrate\u003c/code\u003e、\u003ccode\u003e模块\u003c/code\u003e 概念,本文我们介绍一下它们之间的关系和调用方法。\u003c/p\u003e\n\u003ch1 id=\"包-和-crate\"\u003e包 和 Crate\u003c/h1\u003e\n\u003cp\u003e在Rust中,\u003cem\u003e包\u003c/em\u003e(\u003cem\u003epackage\u003c/em\u003e)是提供一系列功能的一个或者多个 crate。一个包会包含一个 \u003ccode\u003eCargo.toml\u003c/code\u003e 文件,阐述如何去构建这些 crate。\u003c/p\u003e\n\u003cp\u003e我们先看一下通过 \u003ccode\u003ecargo new\u003c/code\u003e 创建一个 \u003ccode\u003emy_project\u003c/code\u003e 包。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-shell\" data-lang=\"shell\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e➜ cargo new my_project \n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e Creating binary \u003cspan style=\"color:#f92672\"\u003e(\u003c/span\u003eapplication\u003cspan style=\"color:#f92672\"\u003e)\u003c/span\u003e \u003cspan style=\"color:#e6db74\"\u003e`\u003c/span\u003emy_project\u003cspan style=\"color:#e6db74\"\u003e`\u003c/span\u003e package\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003enote: see more \u003cspan style=\"color:#e6db74\"\u003e`\u003c/span\u003eCargo.toml\u003cspan style=\"color:#e6db74\"\u003e`\u003c/span\u003e keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e➜ rust tree my_project \n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003emy_project\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e├── Cargo.toml\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e└── src\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e └── main.rs\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#ae81ff\"\u003e2\u003c/span\u003e directories, \u003cspan style=\"color:#ae81ff\"\u003e2\u003c/span\u003e files\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e它将创建一个 \u003ccode\u003eCargo.toml\u003c/code\u003e文件,内容:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-toml\" data-lang=\"toml\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e[ …\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e"
June 25, 2024
Rust中将一个结构体拆分成多个文件
"\u003cp\u003e官方文档将\u003ca href=\"https://kaisery.github.io/trpl-zh-cn/ch07-05-separating-modules-into-different-files.html\"\u003e一个模块拆分成多个文件\u003c/a\u003e时,介绍的是将原来多个模块写在同一个文件中,拆分成了每个模块一个文件。不过还有一种情况没有提到,如果一个模块中的某个 struct 实现代码过多时,仍写在同一个模块文件的话,维护成本就显的比较高了,这时我们可能还需要对这个 struct 的实现按某种粒度拆分成多个文件来实现。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-shell\" data-lang=\"shell\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e✗ tree\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e.\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e├── main.rs\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e├── model\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e│ ├── article.rs // 文章相关\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e│ └── user.rs // 用户相关\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e└── model.rs\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e这里是按官方教程拆分后的样子\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ccode\u003earticle.rs\u003c/code\u003e 是文件模块相关实现 -\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003euser.rs\u003c/code\u003e 是与用户相关的实现\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003emodel.rs\u003c/code\u003e 公开模块\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003ccode\u003emodel.rs \u003c/code\u003e\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-rust\" data-lang=\"rust\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e// src/model.rs\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#66d9ef\"\u003epub\u003c/span\u003e \u003cspan style=\"color:#66d9ef\"\u003emod\u003c/span\u003e article;\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#66d9ef\"\u003epub\u003c/span\u003e \u003cspan style=\"color:#66d9ef\"\u003emod\u003c/span\u003e user;\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e\u003ccode\u003epub\u003c/code\u003e 关键字表示该模块是公开的,可以被其他模块访问。\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003emod article\u003c/code\u003e 声明了一个名为 \u003ccode\u003earticle\u003c/code\u003e 的模块,并且 Rust 编译器会在同文件名的目录下( \u003ccode\u003esrc/model/\u003c/code\u003e )找到一个名为 \u003ccode\u003earticle.rs …\u003c/code\u003e\u003c/p\u003e"
November 28, 2023
Rust中与闭包相关的三个trait
"\u003cp\u003e在 Rust 中,闭包就是一种能捕获 \u003ccode\u003e上下文环境变量\u003c/code\u003e 的函数。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-rust\" data-lang=\"rust\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#66d9ef\"\u003elet\u003c/span\u003e range \u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e \u003cspan style=\"color:#ae81ff\"\u003e0\u003c/span\u003e\u003cspan style=\"color:#f92672\"\u003e..\u003c/span\u003e\u003cspan style=\"color:#ae81ff\"\u003e10\u003c/span\u003e;\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#66d9ef\"\u003elet\u003c/span\u003e get_range_count \u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e||\u003c/span\u003e range.count(); \n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e代码里的这个 \u003ccode\u003eget_range_count\u003c/code\u003e 就是闭包,range 是被这个闭包捕获的环境变量。\u003c/p\u003e\n\u003cp\u003e虽然说它是一种函数,但是不通过 \u003ccode\u003efn\u003c/code\u003e 进行定义。\u003cstrong\u003e在 Rust 中,并不把这个闭包的类型处理成 fn 这种函数指针类型,而是有单独的类型定义。\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003e切记这里是将闭包处理成是 \u003ccode\u003e单独的类型定义\u003c/code\u003e,这一点区别与其它开发语言。\u003c/p\u003e\n\u003cp\u003e至于按哪一种类型来处理,这个没有办法得知,因为只有在Rust编译器在编译的时候才可以确定其类型,并且在确定类型时,还需要根据这个闭包捕获上下文环境变量时的行为来确定。\u003c/p\u003e\n\u003ch1 id=\"闭包trait分类\"\u003e闭包trait分类\u003c/h1\u003e\n\u003cp\u003e根据闭包行为划分为三类trait( 主因是受到所有权影响):\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003ccode\u003eFnOnce\u003c/code\u003e 适用于能被调用一次的闭包,\u003ccode\u003e所有闭包\u003c/code\u003e都至少实现了这个 trait,因为所有闭包都必须能够被调用。一个会将捕获的值移出闭包体的闭包只实现 \u003ccode\u003eFnOnce\u003c/code\u003e trait,这是因为它只能被调用一次。其获取了上下文环境变量的所有权。\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eFnMut\u003c/code\u003e 适用于 …\u003c/li\u003e\u003c/ol\u003e"
November 16, 2023
Rust中的迭代器iter
"\u003cp\u003e迭代器模式允许你对一个序列的项进行某些处理。\u003cstrong\u003e迭代器\u003c/strong\u003e(\u003cem\u003eiterator\u003c/em\u003e)负责遍历序列中的每一项和决定序列何时结束的逻辑。当使用迭代器时,我们无需重新实现这些逻辑。\u003c/p\u003e\n\u003cp\u003e在 Rust 中,迭代器是 \u003cstrong\u003e惰性的\u003c/strong\u003e(\u003cem\u003elazy\u003c/em\u003e),这意味着在调用方法使用迭代器之前它都不会有效果。例如,示例中的代码通过调用定义于 \u003ccode\u003eVec\u003c/code\u003e 上的 \u003ccode\u003eiter\u003c/code\u003e 方法在一个 vector \u003ccode\u003ev1\u003c/code\u003e 上创建了一个迭代器。这段代码本身没有任何用处:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-rust\" data-lang=\"rust\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#66d9ef\"\u003elet\u003c/span\u003e v1 \u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003evec!\u003c/span\u003e[\u003cspan style=\"color:#ae81ff\"\u003e1\u003c/span\u003e, \u003cspan style=\"color:#ae81ff\"\u003e2\u003c/span\u003e, \u003cspan style=\"color:#ae81ff\"\u003e3\u003c/span\u003e];\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#66d9ef\"\u003elet\u003c/span\u003e v1_iter \u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e v1.iter();\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e迭代器被储存在 \u003ccode\u003ev1_iter\u003c/code\u003e 变量中。一旦创建迭代器之后,可以选择用多种方式利用它。\u003c/p\u003e\n\u003ch1 id=\"迭代器分类\"\u003e迭代器分类\u003c/h1\u003e\n\u003cp\u003eRust 中迭代器根据 \u003ccode\u003e所有权\u003c/code\u003e 可分为 \u003ccode\u003eiter()\u003c/code\u003e、\u003ccode\u003eiter_mut()\u003c/code\u003e、\u003ccode\u003einto_iter()\u003c/code\u003e 三种迭代器,使用场景:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e获取集合元素不可变引用的迭代器,对应方法为 \u003ccode\u003eiter()\u003c/code\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e获取集合元素可变引用的迭代器,对应方法为 \u003ccode\u003eiter_mut()\u003c/code\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e获取集合元素所有权的迭代器,对应方法为 \u003ccode\u003einto_iter()\u003c/code\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e也就是说当你在 Rust 中看到调用了 \u003ccode\u003eiter()\u003c/code\u003e 方法,则表示这里使用了不可 …\u003c/p\u003e"
November 7, 2023
Rust 中的 Result 与 Option
"\u003cp\u003e在 Rust 中有两个常用的 \u003ccode\u003eenum\u003c/code\u003e 枚举类型,分别为 \u003ccode\u003eResult\u003c/code\u003e 和 \u003ccode\u003eOption\u003c/code\u003e,本节介绍它们两者各自的使用场景和用法。\u003c/p\u003e\n\u003cp\u003e这里我们先给出结论\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e结果 \u003ccode\u003eResult\u003c/code\u003e 表示 \u003ccode\u003e成功\u003c/code\u003e 或 \u003ccode\u003e失败\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e选项 \u003ccode\u003eOption\u003c/code\u003e 表示 \u003ccode\u003e有\u003c/code\u003e 或者 \u003ccode\u003e无\u003c/code\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e当从本地读取一个文件时,这时候可能读取成功,也有可能由于文件不存在或权限不足导致读取时候,这种场景一般就需要使用 \u003ccode\u003eResult\u003c/code\u003e;而当从一组数据集中查询指定元素是否存在时,这时有可能存在,也有可能不存在(用None 表示),这时情况就应该选择Option。\u003c/p\u003e\n\u003cp\u003e由此看到,这两个枚举类型的区别理解起来还是挺简单的,下面我们单独对每一种类型做一下详细的介绍。\u003c/p\u003e\n\u003ch1 id=\"结果-result\"\u003e结果 Result\u003c/h1\u003e\n\u003cp\u003e定义\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-rust\" data-lang=\"rust\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#66d9ef\"\u003eenum\u003c/span\u003e Result\u003cspan style=\"color:#f92672\"\u003e\u0026lt;\u003c/span\u003eT, E\u003cspan style=\"color:#f92672\"\u003e\u0026gt;\u003c/span\u003e {\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e Ok(T),\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e Err(E),\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e}\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e\u003ccode\u003eResult\u0026lt;T, E\u0026gt;\u003c/code\u003e 类型拥有两个取值:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ccode\u003eOk(value)\u003c/code\u003e 表示操作成功,并包装操作返回的 \u003ccode\u003evalue\u003c/code\u003e(\u003ccode\u003evalue\u003c/code\u003e 拥有 \u003ccode\u003eT\u003c/code\u003e 泛类型)。\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eErr(why)\u003c/code\u003e,表示操作失败,并包装 \u003ccode\u003ewhy\u003c/code\u003e,它(但愿)能够解释失败的原因(\u003ccode\u003ewhy\u003c/code\u003e 拥有 \u003ccode\u003eE\u003c/code\u003e 类型)。\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e举个例子,这里打开 …\u003c/p\u003e"