【Rust】18. Rust 的面向对象特性

18.1 面向对象语言的特征

18.1.1 对象:数据 + 行为

在这里插入图片描述

18.1.2 封装隐藏了实现细节

  • 在 Rust 中,在代码中不同的部分考虑使用 pub 可以封装其实现细节

在这里插入图片描述
在这里插入图片描述

18.1.3 继承,作为类型系统与代码共享

  • 在 Rust 中,不存在继承的机制,而是使用 trait 对象来提供相关的功能

在这里插入图片描述

18.2 trait 对象

  • 已知全部的数据类型时,可以使用固定集合(枚举);但当全部的数据类型不是已知时(会动态变化),就需要使用 trait 对象来实现了

在这里插入图片描述

18.2.1 trait 对象(是一个实例):定义通用行为

  • trait 对象:指向一个实现了指定 trait 类型的实例,以及一个用于在运行时查找该类型的 trait 方法的表
  • 通过指定某种**指针(& 引用或 Box<T> 智能指针,还有 dyn 关键字)**来创建 trait 对象
  • 可以使用 trait 对象代替泛型或具体类型,无需在编译时就知晓所有可能的类型
  • trait 对象将数据和行为两者相结合(不同于传统的对象,不能向 trait 对象增加数据),trait 对象的作用是允许对通用行为进行抽象
  • 对比泛型类型:泛型类型参数一次只能替代一个具体类型,而 trait 对象则允许在运行时替代多种具体类型

在这里插入图片描述
在这里插入图片描述

18.2.2 实现 trait

  • 将一个或多个类型的实例放入 Box<T>就可以转换得到 trait 对象!
  • 使用 trait 对象和 Rust 类型系统来进行类似鸭子类型操作的优势是无需在运行时检查一个值是否实现了特定方法或者担心在调用时因为值没有实现方法而产生错误。如果值没有实现 trait 对象所需的 trait 则 Rust 不会编译这些代码

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

18.2.3 trait 对象执行动态分发

在这里插入图片描述

18.2.4 trait 对象需要类型安全

  • 只有**对象安全(object-safe)**的 trait 可以实现为特征对象
  • 如果一个 trait 中定义的所有方法都符合以下规则,则该 trait 是对象安全的:1、返回值不是 Self;2、没有泛型类型的参数
  • 核心原因:一旦使用 trait 对象,Rust 将不再知晓该实现的返回类型!

在这里插入图片描述

18.3 面向对象设计模式的实现

18.3.1 状态模式

  • 状态模式(state pattern):是一个面向对象设计模式,该模式的关键在于定义一系列值的内含状态,这些状态体现为一系列的状态对象,同时值的行为随着其内部状态而改变
  • 状态对象共享功能
  • 每一个状态对象负责其自身的行为,以及该状态何时应当转移至另一个状态。而持有一个状态对象的值,对于不同状态的行为以及何时状态转移毫不知情

在这里插入图片描述
在这里插入图片描述

18.3.2 博客项目(一):定义 Post 并新建一个草案状态的实例

在这里插入图片描述

18.3.3 博客项目(二):存放博文内容的文本

  • 对于需要修改的字段需要传入可变引用 &mut self

在这里插入图片描述

18.3.4 博客项目(三):确保博文草案的内容是空的

在这里插入图片描述

18.3.5 博客项目(四):请求审核博文来改变其状态

  • 代码解析:if let Some(s) = self.state.take() 表示先取出当前 state 的值及其所有权,再给到中间变量 ss 再根据实际获取到的 state 值调用对应的 request_review 方法(即判断是属于 Draft 还是 PendingReviewrequest_review
  • 在这里来看看状态模式的优势:无论 state 是何值,Post 的 request_review 方法都是一样的。每个状态只负责它自己的规则

在这里插入图片描述
在这里插入图片描述

18.3.6 博客项目(五):增加改变 content 行为的 approve 方法

  • 调用 Optionas_ref 方法是因为需要 Option值的引用而不是获取其所有权
  • 在下面的示例中,获取到的 &Box<dyn State>,当调用其 content 时,Deref 强制转换会作用于 &Box
  • 在下面的示例中,获取 post 的引用作为参数,并返回 post 一部分的引用,所以返回的引用的生命周期与 post 参数相关

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

18.3.7 状态模式的权衡取舍

  • 状态模式的优点:Post 的方法和使用 Post 的位置无需 match 语句,同时增加新状态只涉及到增加一个新 struct 和为其实现 trait 的方法
  • 状态模式的缺点:因为状态实现了状态之间的转换,一些状态会相互联系会有一些重复的逻辑(可通过默认方法、定义宏等方法来解决)

在这里插入图片描述

18.3.8 博客项目-改造(一):将状态和行为编码为类型

在这里插入图片描述
在这里插入图片描述

18.3.9 博客项目-改造(二):实现状态转移为不同类型的转换

在这里插入图片描述
在这里插入图片描述

18.4 小结

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值