深入淺出Rust(第三部分-1)


傳送門:
深入淺出Rust(第一部分-1)
深入淺出Rust(第一部分-2)
深入淺出Rust(第二部分-1)
深入淺出Rust(第二部分-2)
深入淺出Rust(第三部分-1)
深入淺出Rust(第三部分-2)
深入淺出Rust(第四部分)
深入淺出Rust(第五部分)


第三部分 - 高級抽象 -1

第21章 泛型

看了引入泛型,就要考慮的方方面面,怪不得Go遲遲拿不出方案了...
Rust的泛型和java的不同,java只是在編譯器進(jìn)行檢查,運(yùn)行是進(jìn)行類型擦除.而Rust是在編譯器時(shí)進(jìn)行檢查和類型綁定.

1.數(shù)據(jù)結(jié)構(gòu)中的泛型

  • Option類型是一個(gè)泛型enum類型
struct S<T=i32>{
    data: T
}
  • 泛型參數(shù)T,使用時(shí)候可以不指定類型,這樣就用了默認(rèn)值i32.

2. 函數(shù)中的泛型

  • 在方法名后面加上<>泛型參數(shù)(與java是一樣)
  • 手動(dòng)指定參數(shù): function_name::<type params>(function params)語法,這里用::分隔
  • 泛型函數(shù)很多程度實(shí)現(xiàn)了C++的"函數(shù)重載"功能,通過對參數(shù)的泛化,是的參數(shù)能接受多種類型

3. impl塊中的泛型

  • impl塊中的泛型: 直接再impl后面<>,并且配合where子句

4. 泛型參數(shù)約定

  • Rust在分析泛型函數(shù)的時(shí)候當(dāng)場檢查類型的合法性
21-1.png

5. 關(guān)聯(lián)類型(難點(diǎn))

  • 在定義trait時(shí)候還同時(shí)定義type,使得在impl時(shí)候,需要同時(shí)指定該類型.
  • 也就是說trait中的泛型,可以不放第一句,而是單獨(dú)說明.
pub trait Iterator{
    type Item;
}
  • 增加可讀性,可擴(kuò)展性;(不用對trait的每個(gè)函數(shù)單獨(dú)指定約束)
  • trait的impl匹配規(guī)則,可以針對不同類型實(shí)現(xiàn)多個(gè)impl,而不會(huì)沖突.

6. 使用關(guān)聯(lián)類型(難點(diǎn))

7. 泛型特化

  • 僅僅針對trait和impl支持特化功能,當(dāng)有多個(gè)impl可用時(shí),編譯器很聰明會(huì)找到最特化的impl
  • 特化意義: 性能優(yōu)化,代碼重用,為"高效繼承"鋪路
  • 使用default關(guān)鍵字,是的impl方法能夠被"重寫",從而完成特化
  • 交叉impl---試驗(yàn)性,并不完美

第22章 閉包

閱讀下來,語義上閉包和js的閉包區(qū)別不大,語法小有區(qū)別

語法:

|a: i32, b: i32| -> i32 { return a+b;} 

簡寫:

|a, b| -> a+b;

省略類型,{},return,這些和java,js倒是一樣的.

1. 變量捕獲

  • 閉包屬于語法糖,Rust中是通過匿名結(jié)構(gòu)體實(shí)現(xiàn)的,它會(huì)捕獲用到的外部變量,傳入內(nèi)部
  • 優(yōu)先選擇&T類型,其次&mut T,最后T類型.(我都要的策略)

2. move關(guān)鍵字

  • 加上move關(guān)鍵字,編譯器生成的匿名結(jié)構(gòu)體都使用by value方式(傳入T類型)
  • 用于閉包需要傳遞到函數(shù)外部的情況

3. Fn/FnMut/FnOnce

  • 閉包還自動(dòng)實(shí)現(xiàn)了幾個(gè)trait
  • FnOnce:傳入self,執(zhí)行一次后失效
  • FnMut: 傳入&mut self,能改變外部環(huán)境變量和自己成員變量
  • Fn: 傳入&self,只能改變外部環(huán)境變量

4. 閉包和泛型(難)

  • 要向函數(shù)傳遞閉包(1. 不同參數(shù)生成不同版本函數(shù):靜態(tài); 2. 進(jìn)行trait object裝箱: 動(dòng)態(tài))

5. 閉包與生命周期(難)

  • 要讓閉包作為返回值,生命周期標(biāo)記控制比較困難->高階生命周期
  • .....再補(bǔ)吧.

第23章 動(dòng)態(tài)分派和靜態(tài)分派(難)

  • Rust可以同時(shí)支持靜態(tài)分派(static dispatch)和動(dòng)態(tài)分派(dynamic dispatch)
  • 所謂動(dòng)態(tài),指在運(yùn)行時(shí)才知道具體調(diào)用哪個(gè)函數(shù)(函數(shù)名是知道的,類型未知)
  • 引入dyn關(guān)鍵字
23-1.png

1. trait object

  • 指向triat的指針(類似于Go的接口指針),其為一個(gè)DST動(dòng)態(tài)大小類型
  • 因此變成"胖指針",同時(shí)包含數(shù)據(jù)地址(data)和虛函數(shù)表(vtable),而虛函數(shù)表包含我們具體需要調(diào)用函數(shù)的地址

2. object safe(需要額外限制,保證trait object的安全)

  • trait有Self:Sized約束時(shí),不允許
  • 函數(shù)中有Self類型作為參數(shù)或者返回類型時(shí),不允許(不能出現(xiàn)在虛函數(shù)表)
  • 當(dāng)函數(shù)第一個(gè)參數(shù)不是self時(shí),不允許(加不到虛函數(shù)表)
  • 當(dāng)函數(shù)有泛型參數(shù)時(shí),不允許(可能出現(xiàn)不同版本,沖突)

3. impl trait(略)

  • .....再補(bǔ)吧.
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容