
Rust代码示例
Rust By Example (RBE) 是一个通过可运行示例来展示 Rust 编程语言各种概念和标准库的集合。
Rust By Example 是一个非常有用的资源,适合初学者和有经验的开发者,通过实际代码示例来深入理解和掌握 Rust 编程语言的各个方面。
fox_lht
这个作者很懒,什么都没留下…
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
Rust代码示例——18.4.2.Result的别名
Rust中可以通过类型别名简化重复使用的Result类型,特别是当错误类型相同时。示例展示了如何为带有ParseIntError的Result定义别名AliasedResult<T>,并在函数中复用该别名。这种用法能减少代码冗余,类似标准库中的io::Result。示例包含两个使用别名的函数:multiply处理字符串乘法,print匹配输出结果,演示了类型别名在实际场景中的应用优势。翻译 2025-08-24 10:50:00 · 0 阅读 · 0 评论 -
Rust代码示例——18.4.1.Result的map
本文介绍了如何处理Rust中的错误传播。通过将字符串解析为整数并相乘的示例,展示了两种错误处理方式:直接使用match语句匹配Result类型,以及使用组合操作符(如and_then和map)简化代码。两种方法都能正确传播ParseIntError错误,但后者代码更简洁。文章还演示了如何打印处理结果,强调组合操作符能提高代码可读性,同时保持相同的错误处理能力。翻译 2025-08-24 10:42:03 · 0 阅读 · 0 评论 -
Rust代码示例——18.4.Result类型
Rust中的Result类型比Option更丰富,能明确返回正确值(Ok)或错误(Err)。Result的unwrap()方法可直接获取值或触发错误。parse()方法常返回Result来处理可能的解析失败。当主函数返回Result类型时,能更优雅地处理错误,返回错误代码而非直接panic。示例展示了如何通过模式匹配处理Result,以及如何让main函数返回Result类型来实现更好的错误处理。翻译 2025-08-24 10:24:13 · 0 阅读 · 0 评论 -
Rust代码示例——18.3.4.将Option解包和缺省操作:or,or_else,get_or_insert,get_or_insert_with
Rust提供了多种处理Option类型的方法:or()立即求值并转移所有权,适合简单回退;or_else()惰性求值,适合复杂或昂贵的操作;get_or_insert()就地修改原始Option,适合初始化场景。这些方法在求值策略、所有权管理和使用意图上各有侧重,or()和or_else()返回新Option,而get_or_insert()返回可变引用。选择时需考虑计算成本、所有权转移和是否需要修改原值,体现了Rust在安全性与性能上的平衡设计。翻译 2025-08-24 09:53:09 · 0 阅读 · 0 评论 -
Rust代码示例——18.3.3.组合操作符:and_then
本文介绍了Rust中map()和and_then()处理Option值的区别。map()会导致嵌套Option(Option<Option<T>>),而and_then()(即flatmap)能直接返回解包后的值。文章通过烹饪示例展示了三种实现方式:传统match、map+flatten和and_then,指出and_then最简洁高效。核心区别在于map()处理返回普通值的函数,而and_then()处理返回Option的函数。翻译 2025-08-23 10:44:31 · 0 阅读 · 0 评论 -
Rust代码示例——18.3.2.组合操作符:map
本文介绍了在Rust中使用map组合操作符优化Option类型处理的方法。通过对比传统match表达式和map链式调用,展示了后者在代码简洁性和可读性上的优势。文章构建了一个食品处理状态机(去皮→切块→煮熟),演示了如何用map自动传播None值,减少样板代码。关键点包括:map的工作原理(保留Some转换,自动跳过None)、处理流程的线性表达、错误处理的自动化特性,以及组合操作的扩展性。最终表明,map链式调用比嵌套match减少70%代码量,同时保持编译时安全性,是处理可选值转换流水线的理想选择。翻译 2025-08-23 09:53:11 · 0 阅读 · 0 评论 -
Rust代码示例——18.3.1.使用符号“?”来解包Option
文章摘要:Rust中的?操作符可以简化Option类型的解包操作,当值为Some时返回内部值,为None时提前返回。文中展示了如何使用?操作符来简化嵌套Option的处理,通过Person结构体获取工作电话区号的例子,对比了传统match语句与?操作符的简洁性差异。这种写法能有效减少嵌套match语句的复杂度,提高代码可读性。翻译 2025-08-22 22:00:24 · 0 阅读 · 0 评论 -
Rust代码示例——18.3.Option和unwrap
本文介绍了Rust中unwrap方法的使用与风险。unwrap能快速解包Option<T>或Result<T,E>类型,在值为Some/Ok时返回内部值,遇到None/Err则触发panic。虽然适合原型开发或确定不会出错的情况,但在生产代码中应避免滥用,因为它会导致程序突然崩溃。建议使用更安全的替代方案:expect提供自定义错误信息、match模式匹配显式处理、?运算符传递错误,或使用unwrap_or设置默认值。这些方法能增强程序健壮性,提供更好的错误处理和用户体验。翻译 2025-08-22 21:46:51 · 0 阅读 · 0 评论 -
Rust代码示例——18.2.about和unwind
摘要:文章展示了Rust中通过panic策略控制错误处理流程的两种方式。第一种示例在函数内部分别处理abort和unwind情况;第二种示例使用属性宏#[cfg]根据不同panic策略定义不同的ah()函数。可通过命令行参数设置panic策略(abort或unwind),运行时会执行对应代码路径。示例以饮料选择为场景,当输入"lemonade"时根据不同策略输出不同警告信息。翻译 2025-08-21 18:46:49 · 1 阅读 · 0 评论 -
Rust代码示例——18.1.panic
Rust中的panic是最简单的错误处理方式,当触发时会打印错误信息并终止程序。示例展示了drink函数在参数为"lemonade"时调用panic!宏立即终止,导致后续代码无法执行。第一次传入"water"正常执行,第二次传入"lemonade"触发panic退出程序,第三次调用不会执行。这种机制适用于不可恢复的错误场景。翻译 2025-08-21 18:44:45 · 3 阅读 · 0 评论 -
Rust代码示例——17.4.可变参数
本文介绍了一个支持可变参数的Rust宏calculate!的设计与实现。该宏通过递归匹配模式处理任意数量的表达式参数,每个参数以"eval"开头。宏内部会分别计算每个表达式的值,并输出"表达式=结果"的格式。在示例中,宏处理了三个表达式参数(1+2、3+4和(2*3)+1),正确输出了各自的运算结果3、7和7。这种设计展示了Rust宏在参数处理上的灵活性,为开发者提供了类似println!宏的可变参数功能。翻译 2025-08-21 17:39:34 · 3 阅读 · 0 评论 -
Rust代码示例——17.3.特定域语言(Domain Specific Languages—DSLs)
Rust宏系统允许创建特定域语言(DSL),通过宏规则将简洁语法扩展到标准Rust结构。示例展示了一个计算器宏,使用eval标识符解析表达式并输出结果。宏定义需注意嵌套括号的语法规则,这种技术在lazy_static等库中广泛应用。该机制能在保持类型安全的同时,提供特定场景下的语法糖。翻译 2025-08-21 17:37:35 · 1 阅读 · 0 评论 -
Rust代码示例——17.2.不要重复编码(Don‘t Repeat Yourself)
本文展示了如何使用Rust宏来避免代码重复,实现向量运算的通用测试。通过定义assert_equal_len!和op!宏,可以批量生成add_assign、mul_assign和sub_assign等向量运算函数。测试模块使用宏自动生成针对不同运算的测试用例,验证了向量加减乘运算的正确性。测试结果显示所有运算(1+2=3、2*3=6、3-2=1)均通过验证,证明了宏在简化重复代码方面的有效性。这种方法显著减少了样板代码,提高了代码的可维护性。翻译 2025-08-21 17:35:53 · 0 阅读 · 0 评论 -
Rust代码示例——17.1.3.重复
摘要:Rust宏通过+/*符号实现参数重复匹配,+表示至少一次,*表示零或多次。示例find_min!宏展示了递归处理可变参数的方法:基础情况处理单个参数,递归情况使用std::cmp::min比较首参数与剩余参数的最小值。这种模式支持灵活的参数处理,适用于数学计算、DSL构建等场景,具有编译时展开、无运行时开销的优势。宏的重复语法$(...),+和$(...),*是实现可变参数处理的核心机制。翻译 2025-08-20 10:29:47 · 4 阅读 · 0 评论 -
Rust代码示例——17.1.2.重载
Rust宏通过参数模式匹配实现重载功能。在示例中,macro_rules!定义的test宏支持两种调用方式:使用"and"比较两个表达式的与运算结果,或使用"or"比较或运算结果。每个模式分支以分号结束,宏根据调用时使用的分隔符(and/or)自动匹配对应逻辑。这种机制类似match表达式,使宏能灵活处理不同参数组合,在编译期生成相应代码。翻译 2025-08-20 10:27:21 · 4 阅读 · 0 评论 -
Rust代码示例——17.1.1.标识符
本文介绍了Rust宏的基本用法,展示了如何通过macro_rules!创建自定义宏。主要内容包括:1)使用ident标识符创建函数宏,如create_function!宏;2)使用expr标识符创建表达式求值宏print_result!;3)演示了宏的实际调用示例。文中还列出了Rust宏中常用的标识符类型,如expr(表达式)、ident(变量/函数名)等,并指出完整标识符列表可参考Rust官方文档。这些宏特性增强了Rust的元编程能力。翻译 2025-08-20 10:25:58 · 3 阅读 · 0 评论 -
Rust代码示例——17.1.语法
本文简要介绍宏定义的基本概念,主要包括模板、标识符和重载重复三个核心要素。宏定义通过模板实现代码复用,利用标识符进行标记替换,并通过重载重复机制实现不同场景下的灵活调用。这些基础概念为掌握宏编程提供了必要框架。翻译 2025-08-20 10:24:32 · 2 阅读 · 0 评论 -
Rust代码示例——17.宏规则
Rust的宏系统支持元编程,通过macro_rules!创建宏,在编译时展开为抽象语法树而非字符串预处理,避免优先级错误。宏能减少代码重复、创建领域特定语言和实现可变参数接口(如println!)。调用时在宏名后加"!",示例展示了简单宏say_hello的定义和使用。翻译 2025-08-20 09:39:00 · 3 阅读 · 0 评论 -
Rust代码示例——16.9.消除接口内重复函数名称的歧义
摘要: 在Rust中,当多个trait(如UsernameWidget和AgeWidget)定义同名方法(如get())且被同一类型实现时,直接调用form.get()会因歧义报错。解决方案是使用全限定语法(<Type as Trait>::method())明确指定目标方法,例如<Form as UsernameWidget>::get(&form)调用字符串版本的get(),而<Form as AgeWidget>::get(&form)调用整数版本。翻译 2025-08-20 09:20:56 · 1 阅读 · 0 评论 -
Rust代码示例——16.8.父接口
Rust通过trait组合实现类似继承的功能。文章展示了如何使用trait超集关系:定义Person作为Student的父trait,而CompSciStudent则同时继承Programmer和Student两个trait。这种组合方式要求实现子trait时必须同时实现所有父trait,并允许在函数参数中使用动态trait对象。示例中的comp_sci_student_greeting函数展示了如何调用来自不同trait的方法,体现了Rust灵活的类型系统设计。翻译 2025-08-19 10:58:07 · 14 阅读 · 0 评论 -
Rust代码示例——16.7.克隆
摘要:Rust中资源默认通过转移所有权来管理,但有时需要创建副本。通过实现Clone trait并调用.clone()方法可实现资源的复制。示例展示了Unit结构体(无资源)可直接复制,而包含资源的Pair结构体需要显式克隆。所有权转移后原变量不可用,但克隆副本仍可继续使用。演示了资源复制、所有权转移和克隆操作的区别。翻译 2025-08-19 10:54:06 · 7 阅读 · 0 评论 -
Rust代码示例——16.6.使用impl trait简化代码
摘要: Rust中impl Trait语法可以简化泛型函数声明,既可作为参数类型也可作为返回类型。作为参数时(如fn f(src: impl BufRead))可替代显式泛型参数;作为返回类型时能简化复杂类型签名(如返回impl Iterator),特别适用于闭包和迭代器组合场景。该语法使代码更简洁,同时支持无法命名的类型(如闭包),但不能显式指定具体类型。示例展示了如何用impl Trait简化CSV解析、迭代器组合和闭包返回等场景。翻译 2025-08-19 10:43:49 · 4 阅读 · 0 评论 -
Rust代码示例——16.5.迭代器
本文介绍了Rust中Iterator接口的使用方法。通过实现next()函数可以自定义迭代器,如斐波那契数列示例。迭代器支持惰性求值,可通过take()、skip()等方法组合使用,并通过for循环消费。不同类型的迭代器(into_iter(),iter(),iter_mut())提供了不同的所有权处理方式。数组等集合可通过iter()方法转换为迭代器进行遍历。这种设计既保持了性能,又提供了灵活的集合操作能力。翻译 2025-08-19 10:00:46 · 4 阅读 · 0 评论 -
Rust代码示例——16.4.销毁
Rust的Drop接口允许在对象离开作用域时自动释放资源,通过实现drop方法可以自定义清理逻辑。示例展示了基本用法:Droppable结构体实现Drop接口打印离开作用域信息;更实际的TempFile示例则自动删除临时文件。资源可在作用域结束时自动释放,也可通过drop函数手动释放。这种机制确保了资源的安全管理,避免了内存泄漏等问题。翻译 2025-08-18 11:04:22 · 7 阅读 · 0 评论 -
Rust代码示例——16.3.重载操作符
Rust通过操作符重载实现类型自定义运算。文中演示了如何为自定义类型Foo和Bar实现Add trait,使它们支持"+"操作。当执行Foo+Bar时调用Foo的add方法返回FooBar,而Bar+Foo则调用Bar的add方法返回BarFoo,展示了非交换性加法的实现。通过core::ops中的Add trait重载操作符,使不同类型可以定义自己的运算行为,增强了代码的灵活性和表达力。翻译 2025-08-18 10:50:54 · 9 阅读 · 0 评论 -
Rust代码示例——16.2.使用dyn动态返回实现trait的类型
Rust中通过Box<dyn Trait>实现动态返回类型。由于Rust需要确定函数返回类型的内存大小,不能直接返回trait对象。解决方法是将对象存储在堆上,通过Box智能指针返回其引用。示例定义了Animal trait及其Sheep和Cow实现,random_animal()函数根据参数返回不同的Animal实现。使用Box<dyn Animal>作为返回类型,既满足编译器要求,又实现了运行时的动态分发。main函数演示了如何调用该函数并使用trait方法。翻译 2025-08-18 10:38:21 · 5 阅读 · 0 评论 -
Rust代码示例——16.1.派生(Derive)
Rust通过#[derive]属性可自动实现常用trait,如比较(Eq/Ord)、复制(Clone/Copy)、哈希(Hash)和格式化(Debug)。示例展示了派生PartialEq和Debug的用法:Centimeters结构体支持比较,Inches结构体可打印输出。手动实现方法如to_centimeters()可实现类型转换。未实现必要trait的类型(如Seconds)无法进行比较或打印操作,这体现了Rust的严格类型安全特性。翻译 2025-08-18 10:21:14 · 1 阅读 · 0 评论 -
Rust代码示例——16.特性接口(trait)
本文展示了Rust中trait(特性接口)的基本用法。通过定义Animal trait和Sheep结构体,演示了如何为类型实现trait,包括定义关联函数(new)、必需方法(name, noise)和带默认实现的方法(talk)。代码中Sheep实现了Animal接口,并覆盖了默认的talk方法,同时展示了结构体自有方法(shear)的调用。主函数创建Sheep实例,演示了剪羊毛前后不同的叫声行为,体现了trait的多态性和方法覆盖特性。这个例子完整展示了Rust接口的定义、实现和使用的核心概念。翻译 2025-08-18 09:48:37 · 2 阅读 · 0 评论 -
Rust代码示例——15.4.9.简写形式(Elision)
Rust编译器通过生命周期省略规则简化常见场景的代码编写。当函数只有输入引用参数时(规则1),编译器自动为每个参数分配独立生命周期;当单输入引用返回引用时(规则2),返回值的生命周期与输入相同;对于方法调用(规则3),返回引用的生命周期与self一致。这些规则在保证内存安全的同时,减少了显式生命周期标注的冗余,使代码更简洁。但要注意不能返回局部变量的引用,因为其生命周期短于输入参数。翻译 2025-08-17 16:05:28 · 8 阅读 · 0 评论 -
Rust代码示例——15.4.8.静态声明
摘要:Rust中的'static生命周期有两种用法:作为引用生命周期和trait约束。作为引用时,表示数据在整个程序运行期间都有效,可通过static常量或字符串字面量创建。示例展示了如何将'static引用强制转换为更短的生命周期。作为trait约束时,要求类型不包含非静态引用,拥有所有权的数据满足该约束,但引用不满足。编译器会检查引用的生命周期是否符合'static要求。翻译 2025-08-17 15:34:40 · 9 阅读 · 0 评论 -
Rust代码示例——15.4.7.生命周期强制转换(Coercion)
Rust通过生命周期强制转换实现引用安全使用。当长生命周期引用与短生命周期引用交互时,编译器会自动推断最小公共生命周期(如multiply函数),或通过显式约束(如'a:'b)将长生命周期转换为短生命周期。示例中,外层first变量被强制转换为内层second的生命周期,确保在短作用域内安全使用。这种机制既支持自动推断也允许手动声明,保障内存安全同时保持灵活性。翻译 2025-08-17 11:02:07 · 6 阅读 · 0 评论 -
Rust代码示例——15.4.6.生命周期的边界
Rust生命周期边界机制解析:通过T:'a语法确保泛型类型中的引用有效性。该机制要求:1)当T包含引用时,这些引用必须比指定生命周期'a更长;2)可与trait约束结合使用(如T:Debug+'a)。示例展示了如何在结构体Ref<'a,T>和函数print_ref中应用此机制,确保被引用的数据比使用者存活更久。编译器会递归检查所有嵌套引用的生命周期有效性,防止悬垂引用。该设计是Rust内存安全的核心保障之一,特别适用于处理复杂引用场景和trait对象。翻译 2025-08-17 10:41:08 · 8 阅读 · 0 评论 -
Rust代码示例——15.4.5.接口
本文介绍了Rust中生命周期在trait和impl块中的使用规则。要点包括:1) trait方法中的生命周期与普通函数规则一致;2) impl块需要声明与结构体相同的生命周期参数;3) 返回局部值引用会导致悬垂引用错误;4) 正确的实现应使用静态生命周期或静态变量;5) 结构体定义、impl块和方法签名需要保持生命周期参数的一致性;6) 当trait方法没有输入引用时,通常需要返回'static生命周期;7) 关联类型也可能需要生命周期标注。文中还提供了错误示例和正确实现方式,以及迭代器trait中使用生命翻译 2025-08-16 17:00:32 · 11 阅读 · 0 评论 -
Rust代码示例——15.4.4.结构体和枚举
Rust允许在结构体和枚举中声明生命周期参数。结构体使用语法<'a>标注,要求引用字段必须包含相同生命周期,且被引用的数据必须比结构体实例存活更久。枚举可以混合存储值类型和引用类型,当包含引用变体时需声明生命周期。代码示例展示了Borrowed结构体和Either枚举的生命周期使用,强调编译器会确保引用数据的有效性,防止悬垂引用。这种机制在保证内存安全的同时,允许灵活组合值类型和引用类型。翻译 2025-08-16 16:42:56 · 10 阅读 · 0 评论 -
Rust代码示例——15.4.3.方法
Rust结构体方法生命周期声明规则与函数相同,引用参数需显式标注。示例展示了两种典型方法:add_one通过&'a mut self获取可变引用,保证独占访问;print通过&'a self获取不可变引用。虽然简单场景下编译器可自动推断,但返回内部引用或多引用参数时必须显式声明生命周期以确保引用有效性。方法语法本质是编译器提供的语法糖,底层生命周期机制与独立函数完全一致。翻译 2025-08-16 16:28:57 · 12 阅读 · 0 评论 -
Rust代码示例——15.4.2.函数
摘要: Rust的生命周期机制确保引用在函数使用期间有效,要求返回引用的生命周期必须与输入参数匹配(如pass_x函数)。禁止返回局部数据的引用(如无效的invalid_output),避免悬垂指针。可变引用(如add_one)同样遵循生命周期规则。通过编译期检查,Rust在保证内存安全的同时,允许灵活处理不同生命周期的引用。示例展示了生命周期标注如何约束函数签名,防止无效访问。翻译 2025-08-16 15:57:13 · 6 阅读 · 0 评论 -
Rust代码示例——15.4.1.显式声明生命周期
Rust中的生命周期注解用于显式声明引用的有效期。语法使用单引号(如'a)作为生命周期参数,可以指定单个或多个生命周期(如<'a,'b>)。示例展示了带生命周期参数的函数print_refs,它要求两个引用的生命周期至少与函数本身一样长。而failed_borrow函数则演示了生命周期不匹配的错误:短生命周期变量无法强制转换为更长的生命周期。在main函数中,正确借用的变量需要确保其生命周期长于借用者。未约束的生命周期默认使用'static。翻译 2025-08-15 11:04:50 · 9 阅读 · 0 评论 -
Rust代码示例——15.4.生命周期
本文介绍了Rust中生命周期(lifetime)的概念及其与作用域(scope)的区别。生命周期是编译器用来确保借用有效的机制,从变量创建开始到销毁结束。虽然生命周期和作用域常被同时提及,但二者并不相同:生命周期关注变量的有效时间范围,而作用域关注引用可访问的范围。文中通过代码示例展示了变量i及其两个借用borrow1和borrow2的生命周期和作用域关系,说明生命周期可以跨越多个作用域。最后指出生命周期不需要显式命名或类型标注,这种设计带来了使用上的限制。翻译 2025-08-15 09:43:00 · 7 阅读 · 0 评论 -
Rust代码示例——15.3.3.引用和模板匹配
摘要:Rust中的ref关键字用于在模式匹配或解构时获取引用。它可以用于结构体字段(如Point{x: ref ref_to_x})和元组元素(如(_, ref mut last)),相当于使用&操作符。ref可与mut组合创建可变引用,如y: ref mut mut_ref_to_y可修改结构体字段。示例展示了如何通过ref解构结构体和元组,并演示了可变引用修改值的用法。ref提供了一种便捷的模式匹配引用方式。翻译 2025-08-14 10:04:58 · 9 阅读 · 0 评论 -
Rust代码示例——15.3.2.别名
摘要:Rust借用规则规定,不可变借用可以多次进行,而可变借用同一时间只能存在一次。示例代码展示了如何对一个结构体进行不可变借用和可变借用,并演示了借用冲突时的编译错误。关键点包括:不可变借用期间不能进行可变借用,可变借用期间不能进行不可变借用,且借用作用域结束后才能重新借用。这些规则保证了Rust的内存安全性。翻译 2025-08-14 09:57:26 · 12 阅读 · 0 评论