網站首頁 編程語言 正文
前言
面向對象的編程語言通常實現了數據的封裝與繼承并能基于數據調用方法。“設計模式四個小幫手”在《設計模式》中給出面向對象的定義:面向對象的程序由對象組成,對象包裝了數據和操作這些數據的過程,這些過程通常被稱作方法或操作。Rust
并不是面向對象的語言,但是面向對象的功能都可以通過自身的特點來實現。
1、實現封裝(pub)
調用對象外部的代碼無法直接訪問對象內部的實現細節,唯一可以與對象進行交互的方法就是通過它公開的 API
,在Rust 中使用 pub
關鍵字來供外部訪問。
封裝的示例:
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; } }
代碼解釋:
- 結構體 AveragedCollection 含有list動態集合與average 兩個變體
- 結構體被pub修飾,可以被外部訪問,但是兩個變體不可以被訪問
- 兩個變體的修改交給下面定義的其他pub修飾的方法
- add與remove 完成list集合的元素添加與刪除,默認調用封裝的更新方法
- update_average 用來更新平均數,而average方法被pub修飾,外部可以直接訪問平均數
由此示例可知
Rust
結構體等類型默認是私有的,相當于C++/Java
中的private
,而被pub
修飾后相當于public
,合理利用這些關鍵字可以做到封裝的效果。
2、實現繼承(trait)
繼承可以使對象沿用另外一個對象的數據和行為,無需定義相關代碼,代碼復用效率高。Rust
中不存在繼承,但是可以通過 trait
方法來實現代碼共享,且可以在 trait
中覆蓋定義的方法,這就相當于主流語言中的子類繼承父類與重寫父類方法。
2.1、為共有行為定義一個 Trait
Rust 避免將 struct
或 enum
稱為對象,因為它們與impl
塊是分開的。
- trait對象有些類似于其它語言中的對象:
- 它們某種程度上組合了數據與行為
- trait 對象與傳統對象不同的地方:
- 無法為 trait對象添加數據
- trait對象被專門用于抽象某些共有行為,它沒其它語言中的對象那么通用
2.2、Trait 對象執行的是動態派發
- 將trait約束作用于泛型時,Rust編譯器會執行單態化:
- 編譯器會為我們用來替換泛型類型參數的每一個具體類型生成對應函數和方法的非泛型實現
- 通過單態化生成的代碼會執行靜態派發(static dispatch),在編譯過程中確定調用的具體方法
- 動態派發(dynamic dispatch) :
- 無法在編譯過程中確定你調用的究竟是哪一種方法
- 編譯器會產生額外的代碼以便在運行時找出希望調用的方法
- 使用trait 對象,會執行動態派發:
- 產生運行時開銷
- 阻止編譯器內聯方法代碼,使得部分優化操作無法進行
2.3、Trait對象必須保證對象安全
- 只能把滿足對象安全(
object-safe
)的 trait 轉化為 trait 對象。 - Rust采用一系列規則來判定某個對象是否安全,只需記住兩條:
- 方法的返回類型不是
Self
- 方法中不包含任何泛型類型參數
- 方法的返回類型不是
3、實現多態(結合泛型)
繼承是多態(Polymorphism
)思想的實現,多態指的是編程語言可以處理多種類型數據的代碼,在 Rust
中使用泛型與 trait 約束(限定參數化多態 bounded parametric
)模擬多態的使用。
有關Rust 泛型與特性的知識在本專欄前面已經介紹過,幫大家放個鏈接:Rust 泛型與特性
4、面向對象的設計模式
狀態模式(state pattern
)是一種面向對象設計模式:
- 一個值擁有的內部狀態由數個狀態對象(state object)表達而成,而值的行為則隨著內
- 部狀態的改變而改變
- 使用狀態模式意味著:
- 業務需求變化時,不需要修改持有狀態的值的代碼,或者使用這個值的代碼
- 只需要更新狀態對象內部的代碼,以便改變其規則。或者增加一些新的狀態對象
- 狀態模式的缺點:
- 某些狀態之間是相互耦合的
- 需要重復實現一些邏輯代碼
Rust不僅能夠實現面向對象的設計模式,還可以支持更多的模式,例如:
將狀態和行為編碼為類型:
Rust 類型檢查系統會通過編譯時錯誤來阻止用戶使用無效的狀態。
面向對象的經典模式并不總是Rust編程實踐中的最佳選擇,因為Rust具有所有權等其它面向對象語言沒有的特性!
原文鏈接:https://blog.csdn.net/m0_58618795/article/details/127477780
相關推薦
- 2022-08-16 C++超詳細梳理基礎知識_C 語言
- 2023-03-25 Pandas快速合并多張excel表格的兩種方法_python
- 2022-11-01 python一行輸入多值的實現詳解_python
- 2022-04-28 Python的命令行參數實例詳解_python
- 2022-10-08 Golang?Web?框架Iris安裝部署_Golang
- 2022-06-15 axios?gin的GET和POST請求實現示例_Golang
- 2022-05-11 并發編程之CAS和Atomic原子操作類
- 2023-03-20 C#中如何限制TextBox控件內輸入值的范圍_C#教程
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支