Rust9.1 Object-Oriented Programming Features of Rust

Rust学习笔记

Rust编程语言入门教程课程笔记

参考教材: The Rust Programming Language (by Steve Klabnik and Carol Nichols, with contributions from the Rust Community)

Lecture 17: Object-Oriented Programming Features of Rust

src/main.rs

rust 复制代码
use oop::Draw;
use oop::{Button, Screen};

use oop::Post;
use oop::Post2;

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

impl Draw for SelectBox {
    //The trait object is then responsible for calling the draw method at runtime
    fn draw(&self) {
        // code to actually draw a select box
    }
}

fn main() {
    //Using Trait Objects That Allow for Values of Different Types
    let screen = Screen {
        components: 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();

    //Implementing an Object-Oriented Design Pattern
    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());

    //Using Trait Objects That Allow for Values of Different Types
    let mut post = Post2::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());
}

src/lib.rs

rust 复制代码
//Object-Oriented Programming: Object, Encapsulation, Inheritance, Polymorphism

//Encapsulation: A unit of code that hides its implementation details and exposes a public API.
pub struct AveragedCollection {
    list: Vec<i32>,
    average: f64,
}

impl AveragedCollection {
    pub fn add(&mut self, value: i32) {
        self.list.push(value);
        self.update_average();
    }

    pub fn remove(&mut self) -> Option<i32> {
        let result = self.list.pop();
        match result {
            Some(value) => {
                self.update_average();
                Some(value)
            }
            None => None,
        }
    }

    pub fn average(&self) -> f64 {
        self.average
    }

    fn update_average(&mut self) {
        let total: i32 = self.list.iter().sum();
        self.average = total as f64 / self.list.len() as f64;
    }
}

//Using Trait Objects That Allow for Values of Different Types
pub trait Draw {
    fn draw(&self);
}

pub struct Screen {
    pub components: Vec<Box<dyn Draw>>, //dyn: dynamic dispatch
}

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

//Implementing the Trait
pub struct Button {
    pub width: u32,
    pub height: u32,
    pub label: String,
}

impl Draw for Button {
    //The trait object is then responsible for calling the draw method at runtime
    fn draw(&self) {
        // code to actually draw a button
    }
}

//Implementing an Object-Oriented Design Pattern

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(){//take() method to move the Some value out of state
            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
    }
}

//Using Trait Objects That Allow for Values of Different Types

pub struct Post2{
    content: String,
}

pub struct DraftPost{
    content: String,
}

impl Post2{
    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) -> Post2{
        Post2{
            content: self.content,
        }
    }
}
相关推荐
刘发财4 小时前
前端2秒生成500页矢量PDF,rust真的强到没朋友
前端·javascript·rust
M78佐菲4 小时前
51单片机学习笔记:ds18b20要点整理
linux·笔记·嵌入式硬件·学习·51单片机
蒸蒸yyyyzwd6 小时前
从面经中学到的三件事
c++·笔记
yume_sibai6 小时前
06-Rust Web 开发实战(Axum 框架 + 数据库 + JWT 认证 + 中间件 + 部署)
前端·数据库·rust
IT小白杨8 小时前
社媒多账号运营的环境隔离:一张图谱模型,解释清“为什么换IP还是被连坐“
经验分享·笔记·矩阵·指纹浏览器
PC2005-cloud11 小时前
Rust学习笔记:控制流——if、loop、while、for与match
笔记·学习·rust
IT笔记12 小时前
Rust 迭代器多级链式调用执行顺序笔记
开发语言·笔记·rust
kyrie_sakura12 小时前
python学习笔记14 -- FastAPI
笔记·python·学习·fastapi
Kapaseker12 小时前
以为 Rust 快了 50000 倍,结果编译器根本没算
rust
传奇开心果编程13 小时前
【Xilem 0.4 基础语法学与练】第11课(深入篇):为什么其他 Rust 框架不是一切皆设计图
学习·rust·前端框架