1. 程式人生 > 其它 >Rust的面向物件程式設計特性-為使用不同型別的值而設計的trait物件

Rust的面向物件程式設計特性-為使用不同型別的值而設計的trait物件

  由於Rust並沒有繼承,因此我們通過其它方法來實現類似繼承的功能。為了展示如何實現這一點,這裡將建立一個圖形使用者介面(Graphical User Interface)工具的例子,它通過遍歷列表並呼叫每一個專案的draw方法來將其繪製到螢幕上--此是一個gui工具的常見技術。我們所知曉的是gui需要記錄一系列不同型別的值,並需要能夠對其中每一個值呼叫draw方法。這裡無需知道呼叫draw方法時具體會發生什麼,只要該值會有那個方法可供我們呼叫。

  在擁有繼承的語言中,要以定義一個名為Component的類,該類上有一個draw方法。其他的類比如Button、Image會從Component 派生並因此繼承draw方法。它們各自都可以覆蓋draw方法來定義自已的行為,但是框架會把所有這些型別當作是Component的例項,並在其上呼叫draw。

定義通用行為的trait

  為了實現gui所期望的行為,讓我們定義一個Draw trait,其中包含名為draw的方法。接著可以定義一個存放trait物件(trait object)的vector。trait物件指向一個實現了我們指定trait的型別的例項,以及一個用於在執行時查代該型別的trait方法的表。我們通過指定某種指標來建立trait物件,例如 & 引用或 Box<T> 智慧指標,琿有dyn keyword,以及指定相關的trait。我們可以使用trait物件代替泛型或具體型別。任何使用trait物件的位置,Rust的型別系統會在編譯時確保任何在此上下文中使用的值會實現其trait物件的trait。如此便無需在編譯時就知曉所有可能的型別。

  Rust刻意不將結構體與列舉稱為“物件”,以便與其它語言中的物件相區別。在結構體或列舉中,結構體欄位中的資料和impl塊中的行為是分開的,不同於其它語言中將資料和行為組合進一個稱為物件的概念中。trait物件將資料和行為兩者相結合,從這種意義上說則其更類似其它語言中的物件。不過trait物件不同於傳統的物件,因為不能向trait物件增加資料。trait物件並不像其它語言中的物件那麼通用:其(trait物件)具體的作用是允許對通用行為進行抽象。