最新要闻
- 【全球报资讯】手机系统相册在哪里(手机系统相册在哪里打开)
- 世界今日讯!邓紫棋的祝福
- 4nm Zen4!宏碁全球抢发AMD锐龙9 7940H笔记本:配个RTX 4050 焦点快报
- 环球热文:苹果最强对手来了!小米13 Ultra首销:5999元买安卓影像之王
- 马斯克准备了7年的超级火箭炸了!但员工们乐得开起了香槟
- 世界百事通!迪士尼真人版《小美人鱼》新写真出炉:黑美人鱼海底双手托腮
- 五一民宿预订现涨价退单潮 房东找奇葩理由:破产不干了
- ST时万(600241)2023年一季报财务简析:净利润减48.39%
- 当前最新:用户侧100千瓦时锌溴液流电池系统并网运行
- 全球观天下!上市险企财险2022年年报:综合费用率均有下降
- 一带一路、中字头个股午后反弹 西藏天路反包涨停
- 女生戒指戴法的含义图解_女生戒指戴法的含义|速读
- 农村厕所要怎么改造
- 世界今热点:三只小山羊创始人杨玉勇:专业、专注、全力以赴,成就羊绒大衣专家
- 已致270人死亡,2600余人受伤!中国驻苏丹使馆:请尽快登记! 今日播报
- 21世纪仅有7次!罕见日全环食今天来了|最新
广告
手机
iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
- 警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- 男子被关545天申国赔:获赔18万多 驳回精神抚慰金
- 3天内26名本土感染者,辽宁确诊人数已超安徽
- 广西柳州一男子因纠纷杀害三人后自首
- 洱海坠机4名机组人员被批准为烈士 数千干部群众悼念
家电
全球热点!Rust编程语言入门之Rust的面向对象编程特性
(资料图片)
Rust 的面向对象编程特性
一、面向对象语言的特性
Rust是面向对象编程语言吗?
- Rust 受到多种编程范式的影响,包括面向对象
- 面向对象通常包含以下特性:命名对象、封装、继承
对象包含数据和行为
- “设计模式四人帮”在《设计模型》中给面向对象的定义:
- 面向对象的程序由对象组成
- 对象包装了数据和操作这些数据的过程,这些过程通常被称作方法或操作
- 基于此定义:Rust是面向对象的
- struct、enum 包含数据
- impl 块为之提供了方法
- 但带有方法的 struct、enum 并没有被称为对象
封装
- 封装:调用对象外部的代码无法直接访问对象内部的实现细节,唯一可以与对象进行交互的方法就是通过它公开的 API
- Rust:pub 关键字
pub struct AveragedCollection { list: Vec, average: f64,}impl AveragedCollection { pub fn add(&mut self, value: i32) { self.list.push(value); self.update_average(); } pub fn remove(&mut self) -> Option { 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; }}
继承
- 继承:使对象可以沿用另外一个对象的数据和行为,且无需重复定义相关代码
- Rust:没有继承
- 使用继承的原因:
- 代码复用
- Rust:默认 trait 方法来进行代码共享
- 多态
- Rust:泛型和 trait 约束(限定参数化多态 bounded parametric)
- 代码复用
- 很多新语言都不使用继承作为内置的程序设计方案了。
二、使用 trait 对象来存储不同类型的值
有这样一个需求
- 创建一个 GUI 工具:
- 它会遍历某个元素的列表,依次调用元素的 draw 方法进行绘制
- 例如:Button、TextField 等元素
- 在面向对象语言里:
- 定义一个 Component 父类,里面定义了 draw 方法
- 定义 Button、TextField 等类,继承与 Component 类
为共有行为定义一个 trait
- Rust 避免将 struct 或 enum 称为对象,因为他们与 impl 块是分开的
- trait 对象有些类似于其它语言中的对象:
- 它们某种程度上组合了数据与行为
- trait 对象与传统对象不同的地方:
- 无法为 trait 对象添加数据
- trait 对象被专门用于抽象某些共有行为,它没其它语言中的对象那么通用
Trait 动态 lib.rs 文件
pub trait Draw { fn draw(&self);}pub struct Screen { pub components: Vec>,}impl Screen { pub fn run(&self) { for component in self.components.iter() { component.draw(); } }}pub struct Button { pub width: u32, pub height: u32, pub label: String,}impl Draw for Button { fn draw(&self) { // 绘制一个按钮 }}
泛型的实现 一次只能实现一个类型
pub struct Screen { pub components: Vec,}impl ScreenwhereT: Draw,{ pub fn run(&self) { for component in self.components.iter() { component.draw() } }}
main.rs 文件
use oo::Draw;use oo::{Button, Screen};struct SelectBox { width: u32, height: u32, options: Vec,}impl Draw for SelectBox { fn draw(&self) { // 绘制一个选择框 }}fn main() { 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();}
Trait 对象执行的是动态派发
- 将 trait 约束作用于泛型时,Rust编译器会执行单态化:
- 编译器会为我们用来替换泛型参数的每一个具体类型生成对应函数和方法的非泛型实现。
- 通过单态化生成的代码会执行静态派发(static dispatch),在编译过程中确定调用的具体方法
- 动态派发(dynamic dispatch):
- 无法在编译过程中确定你调用的究竟是哪一种方法
- 编译器会产生额外的代码以便在运行时找出希望调用的方法
- 使用 trait 对象,会执行动态派发:
- 产生运行时开销
- 阻止编译器内联方法代码,使得部分优化操作无法进行
Trait 对象必须保证对象安全
- 只能把满足对象安全(object-safe)的 trait 转化为 trait 对象
- Rust采用一系列规则来判定某个对象是否安全,只需记住两条:
- 方法的返回类型不是 Self
- 方法中不包含任何泛型类型参数
lib.rs 文件
pub trait Draw { fn draw(&self);}pub trait Clone { fn clone(&self) -> Self;}pub struct Screen { pub components: Vec>, // 报错}
三、实现面向对象的设计模式
状态模式
- 状态模式(state pattern)是一种面向对象设计模式:
- 一个值拥有的内部状态由数个状态对象(state object)表达而成,而值的行为则随着内部状态的改变而改变
- 使用状态模式意味着:
- 业务需求变化时,不需要修改持有状态的值的代码,或者使用这个值的代码
- 只需要更新状态对象内部的代码,以便改变其规则,或者增加一些新的状态对象
例子:发布博客的工作流程 main.rs
use blog::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());}
lib.rs 文件
pub struct Post { state: Option>, 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 { "" } 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) -> Box; fn approve(self: Box) -> Box;}struct Draft {}impl State for Draft { fn request_review(self: Box) -> Box { Box::new(PendingReview {}) } fn approve(self: Box) -> Box { self }}struct PendingReview {}impl State for PendingRevew { fn request_review(self: Box) -> Box { self } fn approve(self: Box) -> Box { Box::new(Published {}) }}struct Published {}impl State for Published { fn request_review(self: Box) -> Box { self } fn approve(self: Box) -> Box { self }}
修改之后:
pub struct Post { state: Option>, 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) -> Box; fn approve(self: Box) -> Box; fn content<"a>(&self, post: &"a Post) -> &"a str { "" }}struct Draft {}impl State for Draft { fn request_review(self: Box) -> Box { Box::new(PendingReview {}) } fn approve(self: Box) -> Box { self }}struct PendingReview {}impl State for PendingRevew { fn request_review(self: Box) -> Box { self } fn approve(self: Box) -> Box { Box::new(Published {}) }}struct Published {}impl State for Published { fn request_review(self: Box) -> Box { self } fn approve(self: Box) -> Box { self } fn content<"a>(&self, post: &"a Post) -> &"a str { &post.content }}
状态模式的取舍权衡
- 缺点:
- 某些状态之间是相互耦合的
- 需要重复实现一些逻辑代码
将状态和行为编码为类型
- 将状态编码为不同的类型:
- Rust 类型检查系统会通过编译时错误来阻止用户使用无效的状态
lib.rs 代码:
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 代码:
use blog::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 不仅能够实现面向对象的设计模式,还可以支持更多的模式
- 例如:将状态和行为编码为类型
- 面向对象的经典模式并不总是 Rust 编程实践中的最佳选择,因为 Rust具有所有权等其它面向对象语言没有的特性!
关键词:
-
KMeans_世界观热点
fromsklearn datasetsimportmake_blobsimportmatplotlib pyplotaspltx,y=make_blobs(n_samples=
来源: KMeans_世界观热点
全球热点!Rust编程语言入门之Rust的面向对象编程特性
【Visual Leak Detector】源码下载 世界热讯
【全球报资讯】手机系统相册在哪里(手机系统相册在哪里打开)
世界今日讯!邓紫棋的祝福
4nm Zen4!宏碁全球抢发AMD锐龙9 7940H笔记本:配个RTX 4050 焦点快报
环球热文:苹果最强对手来了!小米13 Ultra首销:5999元买安卓影像之王
马斯克准备了7年的超级火箭炸了!但员工们乐得开起了香槟
世界百事通!迪士尼真人版《小美人鱼》新写真出炉:黑美人鱼海底双手托腮
五一民宿预订现涨价退单潮 房东找奇葩理由:破产不干了
ST时万(600241)2023年一季报财务简析:净利润减48.39%
当前最新:用户侧100千瓦时锌溴液流电池系统并网运行
全球观天下!上市险企财险2022年年报:综合费用率均有下降
一带一路、中字头个股午后反弹 西藏天路反包涨停
女生戒指戴法的含义图解_女生戒指戴法的含义|速读
农村厕所要怎么改造
世界今热点:三只小山羊创始人杨玉勇:专业、专注、全力以赴,成就羊绒大衣专家
已致270人死亡,2600余人受伤!中国驻苏丹使馆:请尽快登记! 今日播报
21世纪仅有7次!罕见日全环食今天来了|最新
天天看点:LCD面板行业复苏,产能向大陆集中,TCL科技等龙头企业有望受益
世界实时:次新股回调多少可以买入?如何买入?
jrsnba直播吧 a直播吧 焦点精选
世界读书日|重读雷锋日记 弘扬雷锋精神 天天新视野
vivo X Fold2:更易用的折叠屏旗舰 “减重不减质”-环球热讯
亮相第十三届中国轻工业信息化大会,360数字中枢引瞩目-全球热门
一季度我国经济发展实现良好开局_全球微动态
霍勒迪:赛前告诉字母哥会为他拿下G2 我们大家都支持他-精选
记录.Net部署Docker-v指令使用
关于Java中对象的向上转型和向下转型
启明星辰(002439.SZ):预计一季度净亏损6300万元至6800万元 同比减亏
每日热点:双喜!巴萨第一次正式报价梅西:砸锅卖铁筹2亿,第8座金球在招手
微头条丨马斯克SpaceX星舰发射失败:惨烈爆炸 当空“放烟花”
人类最强火箭星舰爆炸 马斯克失落 SpaceX回应:祝贺团队完成首次飞行测试
台北101大楼遭雷击罕见瞬间曝光:紫光乍现照亮夜空_天天要闻
《灌篮高手》热映 你为青春补票吗?80/90后熬夜冲向电影院
马斯克SpaceX星舰发射失败 爆炸瞬间动图:一团火球灰飞烟灭 世界快报
全球今热点:金基集团总经理徐谱曾在龙湖任职多年 跳槽频繁但职位挺稳定
[游戏] EasyGame C++
今日最新!【前端可视化】SVG 学习知识点
平稳运行、动能积蓄——透视首季工业经济数据
和刘云天直播与前妻合体,拿郭德纲题字扇亮相,曹云金是懂流量的-热推荐
重庆公积金缴费基数2023多少 缴存基数上限如何计算?
比RTX 4080小一半!RTX 4000 SFF半高卡开卖:万元价格、功耗仅70瓦
资讯推荐:不玩不行?厂商力挺:黑人女主的游戏正越来越多
5999元起!vivo发布上下折叠屏手机X Flip:魔幻3寸外屏、妹纸最爱
聚焦水利,河南再设百亿产业基金 全球独家
微信小程序学习笔记 播报
无凭证条件下的权限获取
快讯:C++ 结构体对齐
债市日报:4月20日
vivo X Flip登场:航空级铝合金中框 3英寸超大外屏
全球首个12.1寸7:5大屏 vivo Pad2屏幕大升级:拒绝低成本_全球观点
【世界独家】最强火箭SpaceX星舰今晚重新发射!现场大雾弥漫:又要延期?
快播:首发2399元起 vivo Pad2平板发布:娱乐与生产力双旗舰
时隔10年 新一代PC硬件杀手:《孤岛危机4》来了
马布里发微博:篮球之神是公平的
安装到c盘和d盘的区别 c盘和d盘的区别
业绩亏损的股票有可能上涨吗?股票的涨跌原理
ASP.NET Core MVC 从入门到精通之wwwroot和客户端库 世界短讯
海思Hi35xx uboot启动分析总结
上平台! 车联网智能化晋级高段位!
PHP 教程_编程入门自学教程_菜鸟教程-免费教程分享-每日快讯
每日热点:中汽协:3月乘用车产销分别完成214.9万辆和201.7万辆 同比分别增长14.3%和8.2%
铜川市气象台发布沙尘暴黄色预警【Ⅲ级/较重】
环球热头条丨最强折叠屏!vivo X Fold2亮相:7项参数全球唯一
《古龙风云录》等86款游戏过审:4月国产游戏版号公布
《灌篮高手》周边卖断货 官方急挂公告:真没货了 亲们!_世界头条
全球最资讯丨科大讯飞Q1营收28.88亿元 即将发布认知大模型
vivo X Fold2外观正式揭晓:双材质拼接设计独特 环球热资讯
世界微速讯:【金融街发布】人民银行:加快新型信息基础设施建设 加快金融数字化转型
快看点丨后悔没早学 两招轻松搞定打印机堵头难题
全球微动态丨冰淇淋只给外国人道歉后 探访风波中的宝马mini展台:有男子免费派发甜筒
上海车展三星推第6代方形电池 UP主吐槽“闲人免进”:护我安全
天天时讯:家用强力灭蚊!雅格充电电蚊拍9.9元起抄底
巨幕大于想象!vivo X Fold2/X Flip折叠屏未发先火:超50万人预约
【天天速看料】2.56万方!南通这里,即将拆除!
环球微头条丨【0基础学爬虫】爬虫基础之自动化工具 Selenium 的使用
焦点精选!易基因:MeRIP-seq等揭示m6A甲基化修饰对抗病毒基因表达的转录调控机制|Cell Rep
关注:深度学习--PyTorch维度变换、自动拓展、合并与分割
【环球新要闻】记录-JS简单实现购物车图片局部放大预览效果
创建本地yum仓库
【世界报资讯】何冰:演员没有理解力就只剩大声说话了
合金弹头觉醒前期最强阵容搭配推荐
【天天热闻】4999元 机械师推出新款创物者X14笔电:RTX2050 4GB独显
当前热讯:小米13/13 Pro/13 Ultra三款机型对比:到底怎么选 一目了然
【快播报】暴雪承认《暗黑破坏神4》洗点费用有点贵 但不会改
沙尘翻过秦岭入川:局地AQI爆表!成都“躲过一劫”
天天短讯!雷军现身比亚迪腾势、仰望展台 用小米13 Ultra狂拍
世界热门:工信部:将实施5G规模化应用工程 指导发布5G行业建设指南
全球时讯:最新持仓浮出水面:百亿级私募左手AI右手“央国企”
【天天播资讯】Natasha Preheating(三)
全球新动态:集合 第二天
环球今热点:24道Python面试练习题
Kubesphere-DevOps-记一次流水线排错
新起点!大数据分布式可视化的 DAG 任务调度系统 Taier 正式发布1.4版本
滚动:蛇怕什么?
环球速递!小米之家人山人海!小米13 Ultra销售火爆
今日热搜:广告内容“量身定制”!谷歌计划使用生成式AI推送广告
天天热门:女子眼球被摘除,竟是痔疮惹的祸!
疯狂育儿模式 长达4年半不吃不喝不挪窝:自虐死亡的章鱼图啥?