【一起学Rust | 设计模式】习惯语法——默认特质、集合智能指针、析构函数

简介: 【一起学Rust | 设计模式】习惯语法——默认特质、集合智能指针、析构函数



前言

Rust 不是传统的面向对象编程语言,它的所有特性,使其独一无二。因此,学习特定于Rust的设计模式是必要的。本系列文章为作者学习《Rust设计模式》的学习笔记以及自己的见解。

本期文章主要介绍Rust设计模式中的习惯语法中的

  • 默认特质
  • 集合智能指针
  • 析构函数

默认特质:Rust在开发中,不能每处都要求实现new方法,为了解决这个问题而实现Default特质,除此以外,还可以与其他的容器一同使用。

集合智能指针:使用Deref特质可以将集合变为智能指针,提供拥有和借用的数据视图。

析构函数:Rust没有提供无论函数如何退出,都将执行的代码。但是,可以使用对象的析构函数来运行必须在退出之前运行的代码。


一、默认特质

在Rust中,许多类型都有一个构造函数,然而这是特定于某种类型的。Rust并没有强制指定每个类型都必须有一个new方法作为构造函数。为了实现这个需求,Rust提供了Default特质,并且可以与其他容器一起使用。

注意:一些容器已经在合适的地方实现的Default特质。

像Cow、Box或Arc这样的单元素容器不仅可以为包含的默认类型实现默认值,还可以自动 #[derive(Default)]为所有字段都实现它的结构,因此实现默认值的类型越多,它就越有用。

另一方面,构造函数可以接受多个参数,而default()方法不能。甚至可以有多个具有不同名称的构造函数,但每个类型只能有一个默认实现。

以下是一个例子

use std::{path::PathBuf, time::Duration};
// 导出默认值
#[derive(Default, Debug, PartialEq)]
struct MyConfiguration {
    // 选项默认为“None”
    output: Option<PathBuf>,
    // 默认空向量
    search_path: Vec<PathBuf>,
    // 持续时间默认为0
    timeout: Duration,
    // 布尔值默认为Flase
    check: bool,
}
impl MyConfiguration {
    // 在这添加setter
}
fn main() {
    // 构建一个拥有默认值的新实例
    let mut conf = MyConfiguration::default();
    // 做一些处理操作
    conf.check = true;
    println!("conf = {:#?}", conf);
    // 部分初始化创建实例
    let conf1 = MyConfiguration {
        check: true,
        ..Default::default()
    };
    assert_eq!(conf, conf1);
}

二、集合智能指针

使用Deref特质可以将集合变为智能指针,提供拥有和借用的数据视图。以下是一个使用的例子。

use std::ops::Deref;
struct Vec<T> {
    data: RawVec<T>,
    //..
}
impl<T> Deref for Vec<T> {
    type Target = [T];
    fn deref(&self) -> &[T] {
        //..
    }
}

Vect<T> 是拥有T的集合,&[T]是借用T的集合,为Vec实现Deref特质,将允许&Vec<T>到&[T]的隐式解引用>

就像String和&str,可以参考一下。

所有权和借用是Rust语言的关键方面。为了提供良好的用户体验,数据结构必须适当考虑这些语义。当实现拥有其数据的数据结构时,提供该数据的借用视图允许更灵活的API。

大多数方法只能为借用的视图实现,然后它们可以隐式地用于所属视图。让客户在借用或取得数据所有权之间进行选择。

注意:边界检查时不考虑仅通过解引用可用的方法和特性,因此使用此模式的数据结构的通用编程可能会变得复杂(请参见Borrow和AsRef特性等)。

三、析构函数

Rust没有提供无论函数如何退出,都将执行的代码。但是,可以使用对象的析构函数来运行必须在退出之前运行的代码。

以下是使用的例子

fn bar() -> Result<(), ()> {
    // 这些不是必须要在函数中定义的,也可以在其他地方定义
    struct Foo;
    // 为Foo实现析构函数
    impl Drop for Foo {
        fn drop(&mut self) {
            println!("exit");
        }
    }
    // _exit的dtor将在退出函数“bar”时运行。
    let _exit = Foo;
    // 用?操作符隐式的返回
    baz()?;
    // 正常返回
    Ok(())
}

如果一个函数有多个返回点,那么在退出时执行代码会变得困难和重复(因此容易出现错误)。这在由于宏而导致返回是隐式的情况下尤其如此。常见的情况是?运算符,如果结果为Err,则返回,但如果结果为Ok,则继续?被用作异常处理机制,但与Java不同(Java最终实现了),无法调度代码在正常和异常情况下运行。Panic也会提前退出函数。

析构函数中的代码将(几乎)始终运行处理Panic、早期返回等。


总结

以上就是本期文章的所有内容,介绍了Rust设计模式中的习惯语法中的三个部分

  • 默认特质
  • 集合智能指针
  • 析构函数

通过本期内容,希望你能够对Rust开发能有更加深入的了解。

目录
相关文章
|
6月前
|
安全 程序员 编译器
C++中的RAII(资源获取即初始化)与智能指针
C++中的RAII(资源获取即初始化)与智能指针
82 0
|
6月前
|
安全 程序员 C++
C++中的智能指针:从原始指针到现代内存管理
C++中的智能指针:从原始指针到现代内存管理
48 0
|
6月前
|
安全 C++ 容器
C++中的智能指针:自动内存管理的利器
C++中的智能指针:自动内存管理的利器
80 0
|
1月前
|
设计模式 SQL 安全
PHP中的设计模式:单例模式的深入探索与实践在PHP开发领域,设计模式是解决常见问题的高效方案集合。它们不是具体的代码,而是一种编码和设计经验的总结。单例模式作为设计模式中的一种,确保了一个类仅有一个实例,并提供一个全局访问点。本文将深入探讨单例模式的基本概念、实现方式及其在PHP中的应用。
单例模式在PHP中的应用广泛,尤其在处理数据库连接、日志记录等场景时,能显著提高资源利用率和执行效率。本文从单例模式的定义出发,详细解释了其在PHP中的不同实现方法,并探讨了使用单例模式的优势与注意事项。通过对示例代码的分析,读者将能够理解如何在PHP项目中有效应用单例模式。
|
2月前
|
Rust 安全 编译器
30天拿下Rust之智能指针
30天拿下Rust之智能指针
32 1
|
1月前
|
Rust API
【Rust学习】09_方法语法
结构体让你可以创建出在你的领域中有意义的自定义类型。通过结构体,我们可以将相关联的数据片段联系起来并命名它们,这样可以使得代码更加清晰。在 impl 块中,你可以定义与你的类型相关联的函数,而方法是一种相关联的函数,允许您指定结构体的实例具有的行为。 但是结构体并不是创建自定义类型的唯一方式:让我们转向 Rust 的 enum 功能,将另一个工具添加到你的工具箱中。
13 0
|
3月前
|
Rust 安全 编译器
30天拿下Rust之语法大全
Rust是一种系统级编程语言,以其独特的所有权系统和内存安全性受到开发者青睐。本文从基本数据类型入手,介绍了标量类型如整数、浮点数、布尔值及字符,复合类型如元组、数组和结构体等。此外,还探讨了变量与常量的声明与使用,条件判断与循环语句的语法,以及函数定义与调用的方法。文章通过示例代码展示了如何使用Rust编写简洁高效的程序,并简要介绍了注释与宏的概念,为读者快速掌握这门语言提供了实用指南。欲获取最新文章或交流技术问题,请关注微信公众号“希望睿智”。
46 1
|
4月前
|
存储 C++ 运维
开发与运维数组问题之指针的定义语法如何解决
开发与运维数组问题之指针的定义语法如何解决
34 6
|
3月前
|
C语言
【C初阶——指针5】鹏哥C语言系列文章,基本语法知识全面讲解——指针(5)
【C初阶——指针5】鹏哥C语言系列文章,基本语法知识全面讲解——指针(5)
|
3月前
|
C语言
【C初阶——指针4】鹏哥C语言系列文章,基本语法知识全面讲解——指针(4)
【C初阶——指针4】鹏哥C语言系列文章,基本语法知识全面讲解——指针(4)