学习rust_day15

面向对象编程特性

隐藏实现细节的封装
对象的实现细节不能被使用该对象的代码访问

  • pub关键字来决定我们代码中的哪些模块、类型、函数和方法应该是公共的
  • 默认情况下其他所有内容都是私有的

继承作为类型系统和代码共享

  • 继承是一种机制,通过它一个对象可以继承另一个对象定义中的元素,从而获得父对象的数据和行为,而无需再次定义它们
  • 在不使用宏的情况下,没有办法定义一个继承父结构体的字段和方法实现的结构体
  • Rust不具有该特性

多态性
可以处理多种类型数据的代码

  • Rust则使用泛型来抽象不同可能的类型,并使用特征边界来强制这些类型必须提供什么。这有时被称为有界参数多态性
  • Rust采用了不同的方法,使用特征对象(trait object)而不是继承

Trait Object

为通用行为定义Trait
Trait Object

  • Rust提供泛型来支持抽象编程,但泛型要求类型在编译期已知
  • Trait对象(Trait Object)是另一种抽象方式:在运行时支持不同类型的值,前提是它们实现了某个trait
  • 类似于OOP中的“接口+多态”或“鸭子类型”

例:

main.rs:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
use trysomething::{Button, Draw, Screen};

struct SelectBox {
width: u32,
height: u32,
options: Vec<String>
}

impl Draw for SelectBox {
fn draw(&self) {
println!("SelectBox!");
}
}

fn main() {
let screen = Screen {
comonents: vec![
Box::new(
SelectBox {
width: 75,
height: 10,
options: vec![
String::from("Yes"),
String::from("Maybe"),
String::from("No")
]
}
),
Box::new(
Button {
width: 50,
height: 10,
label: String::from("OK")
}
)
]
};

screen.run();
}

lib.rs:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
pub trait Draw {
fn draw(&self);
}

pub struct Screen {
pub comonents: Vec<Box<dyn Draw>>, //使用该方法可以创建一个Trait Object
}

impl Screen {
pub fn run(&self) {
for component in self.comonents.iter() {
component.draw();
}
}
}

pub struct Button {
pub width: u32,
pub height: u32,
pub label: String
}

impl Draw for Button {
fn draw(&self) {
println!("Button!");
}
}

面向对象的特性

实现一个__的设计模式 – State Patten

是将某对象定义一些值作为该对象的状态?与代码相分离,方便代码修改时不用在同步修改状态定义?

lib.rs:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
pub struct Post {
state: Option<Box<dyn State>>,
content: String
}

impl Post {
pub fn new() -> Post {
Post {
state: Some(Box::new(Draft {})),
content: String::new()
}
}

pub fn add_text(&mut self, text: &str) {
self.content.push_str(text);
}

pub fn content(&self) -> &str {
self.state.as_ref().unwrap().content(self)
}

pub fn request_review(&mut self) {
if let Some(s) = self.state.take() {
self.state = Some(s.request_review())
}
}

pub fn approve(&mut self) {
if let Some(s) = self.state.take() {
self.state = Some(s.approve())
}
}
}

trait State {
fn request_review(self: Box<Self>) -> Box<dyn State>;
fn approve(self: Box<Self>) -> Box<dyn State>;
fn content<'a>(&self, post: &'a Post) -> &'a str {
""
}
}

struct Draft {}

impl State for Draft {
fn request_review(self: Box<Self>) -> Box<dyn State> {
Box::new(PendingReview {})
}

fn approve(self: Box<Self>) -> Box<dyn State> {
self
}
}

struct PendingReview {}

impl State for PendingReview {
fn request_review(self: Box<Self>) -> Box<dyn State> {
self
}
fn approve(self: Box<Self>) -> Box<dyn State> {
Box::new(Published {})
}
}

struct Published {}

impl State for Published {
fn request_review(self: Box<Self>) -> Box<dyn State> {
self
}

fn approve(self: Box<Self>) -> Box<dyn State> {
self
}

fn content<'a>(&self, post: &'a Post) -> &'a str {
&post.content
}
}

main.rs:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
use trysomething::Post;

fn main() {
let mut post = Post::new();

post.add_text("I ate a salad for lunch today");
assert_eq!("", post.content());

post.request_review();
assert_eq!("", post.content());

post.approve();
assert_eq!("I ate a salad for lunch today", post.content());
}

例2:

lib.rs:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
pub struct Post {
content: String
}

pub struct DraftPost {
content: String
}

impl Post {
pub fn new() -> DraftPost {
DraftPost {
content: String::new()
}
}

pub fn content(&self) -> &str {
&self.content
}
}

impl DraftPost {
pub fn add_text(&mut self, text: &str) {
self.content.push_str(text);
}

pub fn request_review(self) -> PendingReviewPost {
PendingReviewPost {
content: self.content
}
}
}

pub struct PendingReviewPost {
content: String
}

impl PendingReviewPost {
pub fn approve(self) -> Post {
Post {
content: self.content
}
}
}

main.rs:

1
2
3
4
5
6
7
8
9
10
11
12
13
use trysomething::Post;

fn main() {
let mut post = Post::new();

post.add_text("I ate a salad for lunch today");

let post = post.request_review();

let post =post.approve();

assert_eq!("I ate a salad for lunch today", post.content());
}

学习rust_day15
https://zlsf-zl.github.io/2026/03/25/学习rust-day15/
作者
ZLSF
发布于
2026年3月25日
许可协议