一般例子 fn main() { use oop_status::Post; let mut post = Post::new(); post.add_text("I ate a salad for lunch today"); assert_eq!("",post.content()); post.request_reveiw(); assert_eq!("",post.content()); post.approve(); assert_eq!("I ate a salad for lunch today",post.content()); } 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_reveiw(&mut self) { if let Some(s) = self.state.take() { self.state = Some(s.request_reveiw()); } } pub fn approve(&mut self) { if let Some(s) = self.state.take() { self.state = Some(s.approve()); } } } trait State { fn request_reveiw(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_reveiw(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_reveiw(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_reveiw(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 } } 更加过程化的例子(利用 rust 的类型检查特性) fn main() { use oop_rust_status::*; let mut post = Post::new(); post.add_text("text"); let post = post.request_review(); let post = post.approve(); assert_eq!("text",post.content()); } pub struct Post { content: String, } pub struct DraftPost { content: String, } pub struct PendingReviewPost { 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, } } } impl PendingReviewPost { pub fn approve(self) -> Post { Post { content: self.content, } } }