免费国产精品自在自线-91精品国产色综合久久久浪潮-99热久久免费频精品-国产精品国模在线观看-久久亚洲国产精品成人?V秋霞-久久国产一级A片免费播放-亚洲国产欧洲综合97久久-久久国产白嫩美女呻吟高潮

ARTICLE DETAIL

資訊詳情

深耕商務(wù)建站與企業(yè)官網(wǎng)運(yùn)營的一線實(shí)戰(zhàn)洞察。

Rust所有權(quán)與借用檢查:編譯期內(nèi)存管理實(shí)踐

Rust所有權(quán)與借用檢查:編譯期內(nèi)存管理實(shí)踐 寫 Rust 這幾年被問得最多的一句話就是“所有權(quán)到底是個(gè)啥”。我一直覺得這個(gè)中文譯名有點(diǎn)誤導(dǎo)聽起來像某種法律概念實(shí)際上它描述的是一件特別樸素的事一塊內(nèi)存由誰負(fù)責(zé)釋放、什么時(shí)候釋放、釋放之前誰有資格讀寫。C 里這件事靠人腦記賬Java、Go 里這件事交給運(yùn)行時(shí)在后臺掃Rust 選了第三條路——把賬本寫進(jìn)類型系統(tǒng)讓編譯器在編譯期替你記。代價(jià)是你得學(xué)會跟編譯器講道理收益是運(yùn)行時(shí)沒有停頓、沒有懸垂指針、沒有雙重釋放單線程代碼里的迭代器失效問題基本絕跡。這篇筆記把所有權(quán)、借用檢查、生命周期標(biāo)注、智能指針這幾塊串起來講重點(diǎn)放在“它怎么影響內(nèi)存管理”這個(gè)角度而不是復(fù)述語法手冊。適合已經(jīng)能寫點(diǎn) Rust 但總被借用檢查器攔下來的人也適合從 C 或 Go 轉(zhuǎn)過來、想搞清楚心智模型差異的人。下面所有報(bào)錯(cuò)和改法都是我實(shí)際踩過的代碼可以直接抄去跑。1. 三種內(nèi)存管理路線Rust 為什么挑了最難的這條1.1 手動(dòng)管理與垃圾回收各自的賬單先把三條路擺在桌面上對比不然后面很多設(shè)計(jì)取舍會顯得莫名其妙。手動(dòng)管理C、C 的裸指針路線把釋放時(shí)機(jī)完全交給開發(fā)者性能上限最高內(nèi)存布局最可控代價(jià)是任何一次疏忽都會變成線上事故而且這類事故往往在壓力大的時(shí)候才暴露。垃圾回收J(rèn)ava、Go、C# 的默認(rèn)路線把釋放交給運(yùn)行時(shí)開發(fā)者寫得舒服代價(jià)是內(nèi)存占用曲線偏高延遲不可預(yù)測遇到大堆的時(shí)候一次回收能帶來幾十毫秒的抖動(dòng)。Rust 的所有權(quán)系統(tǒng)是第三條路編譯器在編譯期為每個(gè)值推導(dǎo)出唯一的負(fù)責(zé)方負(fù)責(zé)方離開作用域就自動(dòng)釋放檢查全部發(fā)生在編譯期運(yùn)行時(shí)不需要任何額外指令。路線釋放時(shí)機(jī)運(yùn)行時(shí)開銷典型風(fēng)險(xiǎn)延遲可預(yù)測性手動(dòng)管理開發(fā)者調(diào)用 free/delete接近零懸垂指針、雙重釋放、泄漏高垃圾回收運(yùn)行時(shí)掃描判定5% 到 30% 不等看堆大小停頓抖動(dòng)、內(nèi)存峰值高低所有權(quán)系統(tǒng)作用域結(jié)束自動(dòng) drop編譯期檢查運(yùn)行時(shí)為零學(xué)習(xí)曲線、改寫數(shù)據(jù)結(jié)構(gòu)高這張表里最關(guān)鍵的一列是“運(yùn)行時(shí)開銷”。Rust 的所有權(quán)檢查在編譯完成后就消失了生成的機(jī)器碼里沒有任何一條指令是用來“檢查所有權(quán)”的這叫零成本抽象。你付出的是編譯期的思考成本和偶爾的改寫成本換來的是運(yùn)行時(shí)的確定性。1.2 所有權(quán)本質(zhì)上是一套編譯期推導(dǎo)出來的引用計(jì)數(shù)我習(xí)慣用引用計(jì)數(shù)來類比所有權(quán)這個(gè)類比能解釋掉八成的疑惑。真正的引用計(jì)數(shù)比如RcT是在運(yùn)行時(shí)維護(hù)一個(gè)整數(shù)每次克隆加一每次銷毀減一減到零就釋放。所有權(quán)系統(tǒng)做的事情幾乎一樣區(qū)別在于編譯器在編譯期就能推導(dǎo)出每個(gè)值的引用計(jì)數(shù)永遠(yuǎn)是 0 或 1既然結(jié)果只有兩種那就不需要在運(yùn)行時(shí)存這個(gè)整數(shù)了直接把它編碼進(jìn)類型檢查規(guī)則里。所以String被賦值給另一個(gè)變量之后原變量立刻失效——因?yàn)樵诰幾g器的賬本上這個(gè)值的所有者已經(jīng)換人了舊主人再訪問就是越權(quán)。這個(gè)類比還能解釋另一個(gè)現(xiàn)象為什么RcT在 Rust 里被歸到“智能指針”而不是“所有權(quán)”里。因?yàn)橐坏┠阏娴男枰鄠€(gè)所有者編譯期就沒法推導(dǎo)出唯一負(fù)責(zé)方了只能退回到運(yùn)行時(shí)記賬這就是Rc和Arc存在的原因。理解了這個(gè)層次關(guān)系你就不會覺得RcRefCellT是一堆奇怪符號的堆砌而會明白它是“編譯期賬本不夠用時(shí)的降級方案”。1.3 編譯期到底擋住了哪幾類事故具體一點(diǎn)所有權(quán)加借用檢查主要攔四類問題。第一類是釋放后使用C 里指針指著的內(nèi)存已經(jīng)被free掉讀出來是臟數(shù)據(jù)Rust 里編譯器直接告訴你這個(gè)值已經(jīng) move 走了。第二類是雙重釋放兩個(gè)指針指向同一塊堆內(nèi)存析構(gòu)函數(shù)跑兩遍堆管理器直接崩Rust 里因?yàn)橹挥幸粋€(gè)所有者drop只會執(zhí)行一次。第三類是迭代器失效這是 C 里最陰的一類 bug往vector里push_back之后原來的迭代器可能指向已釋放的舊緩沖區(qū)Rust 里你在遍歷v的同時(shí)調(diào)v.push()會直接編譯失敗。第四類是數(shù)據(jù)競爭多個(gè)線程同時(shí)讀寫同一塊內(nèi)存且沒有同步Rust 靠Send和Sync兩個(gè)標(biāo)記 trait 在編譯期就把不安全的共享擋掉。我印象最深的是第三類。早年寫 C 的時(shí)候在一個(gè)循環(huán)里刪元素導(dǎo)致迭代器失效程序在小數(shù)據(jù)量下跑得好好的上線之后數(shù)據(jù)量上來才開始隨機(jī)崩潰查了兩天才定位到。換成 Rust 之后這種寫法連編譯都過不去等于把調(diào)試成本從線上挪到了敲代碼的那幾分鐘。2. 三條鐵律落地move、Copy、Clone 在內(nèi)存里到底做了什么2.1 三條規(guī)則逐條對照內(nèi)存行為所有權(quán)的規(guī)則只有三條但每一條都對應(yīng)著實(shí)實(shí)在在的內(nèi)存動(dòng)作。第一條每個(gè)值有且只有一個(gè)所有者。第二條同一時(shí)刻只能有一個(gè)所有者。第三條所有者離開作用域值被丟棄。這三條合起來的效果是任何一塊堆內(nèi)存的釋放點(diǎn)都是唯一且確定的編譯器在生成代碼的時(shí)候就知道該在哪里插入釋放調(diào)用不需要運(yùn)行時(shí)判斷。拿String舉例。let s1 String::from(hello);這一行會在棧上放一個(gè)三元組指針、容量、長度在堆上放五個(gè)字節(jié)的數(shù)據(jù)。接著let s2 s1;這一行做的事情是把棧上那 24 個(gè)字節(jié)復(fù)制一份給s2堆上的數(shù)據(jù)一個(gè)字節(jié)都不動(dòng)然后編譯器在符號表里把s1標(biāo)記為失效。如果你這時(shí)候?qū)憄rintln!({}, s1)編譯器報(bào) E0382意思是使用了已經(jīng) move 走的值。注意這里沒有發(fā)生任何堆內(nèi)存分配或復(fù)制move 對String這類類型來說是常數(shù)時(shí)間操作。2.2 move 不是“搬家”是所有權(quán)憑證的轉(zhuǎn)移很多人以為 move 會把堆上的數(shù)據(jù)搬到新地址這是個(gè)誤解。move 搬的只是棧上那個(gè)描述符堆數(shù)據(jù)原地不動(dòng)。這也解釋了為什么對大對象做 move 是廉價(jià)的VecT裝一百萬個(gè)元素move 一次也只復(fù)制 24 個(gè)字節(jié)的頭部。真正昂貴的是clone那才是老老實(shí)實(shí)把堆數(shù)據(jù)復(fù)制一份。我用一段代碼把這個(gè)差別量化一下你可以直接跑fn main() { let v1: Vecu64 (0..1_000_000).collect(); let start std::time::Instant::now(); let v2 v1; // move只復(fù)制頭部 println!(move 耗時(shí): {:?}, start.elapsed()); let start std::time::Instant::now(); let v3 v2.clone(); // clone復(fù)制全部堆數(shù)據(jù) println!(clone 耗時(shí): {:?}, start.elapsed()); println!({} {}, v3.len(), std::mem::size_of::Vecu64()); }實(shí)測下來 move 通常是納秒級clone 一百萬個(gè)u64大概在幾百微秒到一毫秒之間取決于內(nèi)存帶寬。這個(gè)差距在高頻路徑上是致命的所以我養(yǎng)成一個(gè)習(xí)慣函數(shù)簽名里能傳引用就傳引用確實(shí)需要轉(zhuǎn)移所有權(quán)才用 move絕不為了圖省事到處寫.clone()。2.3 Copy 與 Clone 的邊界怎么劃Copy和Clone經(jīng)常被混為一談其實(shí)差別很大。Copy是一個(gè)標(biāo)記 trait表示這個(gè)類型的值可以按位復(fù)制賦值之后原變量依然可用。能實(shí)現(xiàn)Copy的類型有兩個(gè)硬性條件所有字段都是Copy并且這個(gè)類型本身沒有實(shí)現(xiàn)Drop。整數(shù)、浮點(diǎn)數(shù)、布爾、字符、裸指針、以及由它們組成的固定大小數(shù)組和元組都是Copy的。String、VecT、BoxT都不是因?yàn)樗鼈児芾碇褍?nèi)存按位復(fù)制會導(dǎo)致兩個(gè)所有者指向同一塊堆這正是所有權(quán)系統(tǒng)要避免的。Clone則是一個(gè)普通 trait需要你顯式調(diào)用.clone()它允許你自定義復(fù)制邏輯比如深拷貝堆數(shù)據(jù)。任何類型都可以實(shí)現(xiàn)Clone包括實(shí)現(xiàn)了Drop的類型。這里有個(gè)常見的性能坑給一個(gè)大結(jié)構(gòu)體derive(Clone)之后在循環(huán)里順手寫.clone()傳參編譯器不會提醒你代碼跑起來才發(fā)現(xiàn)慢得離譜。我的做法是只有在確實(shí)需要獨(dú)立副本的地方才 deriveClone而且在大結(jié)構(gòu)體上會刻意不 derive逼著自己去想清楚到底該傳引用還是轉(zhuǎn)移所有權(quán)。順便說一個(gè)實(shí)測有用的小技巧用std::mem::size_of快速看一眼類型的棧上開銷很多“為什么這個(gè)結(jié)構(gòu)體這么大”的疑惑一測就清楚了fn main() { println!(String {}, std::mem::size_of::String()); // 24 println!(str {}, std::mem::size_of::str()); // 16 println!(Boxu64 {}, std::mem::size_of::Boxu64()); // 8 println!(OptionBoxu64 {}, std::mem::size_of::OptionBoxu64()); // 8 println!(Rcu64 {}, std::mem::size_of::Rcu64()); // 8 }OptionBoxT只占 8 字節(jié)這件事值得單獨(dú)說一下。編譯器發(fā)現(xiàn)Box的指針不可能是零于是用空指針這個(gè)非法值來表示None這叫空指針優(yōu)化。這個(gè)優(yōu)化在鏈表、樹這類遞歸結(jié)構(gòu)里非常關(guān)鍵不然每個(gè)節(jié)點(diǎn)都要多帶一個(gè)字節(jié)的判別位再加對齊填充內(nèi)存占用會明顯上升。2.4 函數(shù)簽名就是一份所有權(quán)契約我一直建議新手把函數(shù)簽名當(dāng)成一份合同來讀。參數(shù)寫T表示調(diào)用方把這個(gè)值的所有權(quán)交出去了函數(shù)返回之后調(diào)用方不能再碰它寫T表示只借來讀函數(shù)內(nèi)部改不了寫mut T表示借來改借用期間調(diào)用方不能用寫self和mut self是同樣的道理只是作用在方法接收者上。一份好的簽名應(yīng)該讓調(diào)用方一眼看出“我還能不能用這個(gè)變量”。fn consume(s: String) - usize { s.len() } // 拿走所有權(quán) fn inspect(s: str) - usize { s.len() } // 只借用讀 fn append(s: mut String, tail: str) { s.push_str(tail); } // 借用改 fn create() - String { String::from(new) } // 交出所有權(quán)這四行基本覆蓋了九成場景。我踩過的一個(gè)坑是函數(shù)參數(shù)寫成String但其實(shí)只讀一下長度結(jié)果調(diào)用方每次都得 clone 一份才能傳進(jìn)去。改成str之后String和字符串字面量都能直接傳調(diào)用方省掉了所有 clone。這個(gè)改動(dòng)看起來小在一個(gè)熱路徑上能省掉可觀的分配次數(shù)。3. 借用檢查器到底在檢查什么3.1 共享不可變、獨(dú)占可變借用規(guī)則只有一句話任意時(shí)刻你要么擁有多個(gè)不可變引用要么擁有一個(gè)可變引用兩者不能同時(shí)存在。另外所有引用必須始終有效。這條規(guī)則的動(dòng)機(jī)有兩個(gè)層次。淺層是為了防止數(shù)據(jù)競爭多個(gè)線程同時(shí)讀是安全的只要有寫就必須獨(dú)占。深層是為了防止同一份數(shù)據(jù)在讀取過程中被別處改掉導(dǎo)致讀到的內(nèi)容前后不一致。舉一個(gè)最典型的例子遍歷的同時(shí)修改集合fn main() { let mut v vec![1, 2, 3]; for x in v { if *x 2 { v.push(4); // 報(bào)錯(cuò) E0502 } } }編譯器會告訴你v已經(jīng)被不可變借用不能再作為可變借用。這個(gè)限制在 C 里是允許的代價(jià)是push可能觸發(fā)重新分配原來的迭代器變成懸垂指針接著就是未定義行為。Rust 直接把這條路堵死。正確的寫法是先收集要改的內(nèi)容循環(huán)結(jié)束后再統(tǒng)一改fn main() { let mut v vec![1, 2, 3]; let need_push v.iter().any(|x| x 2); if need_push { v.push(4); } }這種“先讀后寫”的拆分模式我用了無數(shù)次幾乎所有的借用沖突都能用這個(gè)思路化解。它看起來多寫了一行實(shí)際上是把原本隱藏的時(shí)序依賴顯式化了代碼反而更清楚。3.2 NLL 讓借用的結(jié)束點(diǎn)變聰明了早期的 Rust 用詞法作用域判斷借用何時(shí)結(jié)束只要變量還在作用域里借用就算沒結(jié)束于是很多寫法通不過。從 2018 edition 開始默認(rèn)啟用非詞法生命周期NLL借用的有效期縮短到“最后一次使用”為止。這個(gè)改進(jìn)影響巨大很多以前必須用花括號強(qiáng)行劃作用域的代碼現(xiàn)在可以直接寫。fn main() { let mut data vec![1, 2, 3]; let first data[0]; println!({}, first); // first 的最后一次使用 data.push(4); // 現(xiàn)在合法了借用已經(jīng)結(jié)束 println!({:?}, data); }這段代碼在老版本會報(bào)錯(cuò)因?yàn)閐ata的可變借用和first的不可變借用被認(rèn)為在同一個(gè)作用域里共存。NLL 之后編譯器看出first在println之后就沒用了借用提前結(jié)束后面的push就不沖突了。理解這一點(diǎn)很重要它意味著你不需要為了繞開借用檢查而寫一堆莫名其妙的花括號只要讓借用自然地在最后一次使用處結(jié)束就行。3.3 生命周期標(biāo)注不延長壽命只是描述關(guān)系生命周期這個(gè)詞嚇退過不少人其實(shí)它的作用被嚴(yán)重夸大了。生命周期標(biāo)注不會讓任何值的存活時(shí)間變長或變短它只是告訴編譯器“這幾個(gè)引用之間的存活關(guān)系是這樣的”方便編譯器做檢查。真正決定值活多久的永遠(yuǎn)是它所在的作用域。最經(jīng)典的例子是返回兩個(gè)字符串切片里較長的那個(gè)fn longesta(x: a str, y: a str) - a str { if x.len() y.len() { x } else { y } }不寫標(biāo)注的話編譯器報(bào) E0106因?yàn)樗鼰o法確定返回的引用到底跟著x還是y活。a的意思是返回值的存活時(shí)間不會超過x和y中較短的那個(gè)。這是一個(gè)上界約束不是延長。調(diào)用方拿到返回值之后只要保證在x和y都還活著的時(shí)候用它就行。生命周期省略規(guī)則有三條記住這三條能省掉大部分手寫標(biāo)注。第一每個(gè)引用參數(shù)各自獲得一個(gè)獨(dú)立的生命周期參數(shù)。第二如果只有一個(gè)輸入引用參數(shù)那么輸出的生命周期全部等于它。第三如果有self或mut self那么輸出的生命周期全部等于self的。第三條是方法簽名的常用規(guī)則所以大多數(shù)方法不需要手寫生命周期標(biāo)注。3.4 結(jié)構(gòu)體持有引用必須寫生命周期這是新手最容易卡住的地方。結(jié)構(gòu)體里如果放了引用就必須給結(jié)構(gòu)體加生命周期參數(shù)因?yàn)榫幾g器需要確保這個(gè)引用比結(jié)構(gòu)體本身活得久。否則結(jié)構(gòu)體還存在的時(shí)候它指向的數(shù)據(jù)可能已經(jīng)被釋放了。struct Tokena { text: a str, line: usize, } impla Tokena { fn len(self) - usize { self.text.len() } }Tokena讀作“這個(gè) Token 的有效期不能超過a”。這意味著任何持有Token的地方那個(gè)被引用的字符串也得活著編譯器會一路向上檢查。這個(gè)傳播有時(shí)候會很煩一個(gè)底層結(jié)構(gòu)加了生命周期上面三層都得跟著加。我的處理策略是分場景的。如果這段數(shù)據(jù)是短命的、臨時(shí)的、解析完就用完的那就老老實(shí)實(shí)加生命周期零拷貝最快。如果這段數(shù)據(jù)要被存起來、跨函數(shù)傳遞、或者放進(jìn)集合里長期持有那就直接存String用一次分配換掉整條鏈上的生命周期標(biāo)注。這個(gè)取舍在下一節(jié)的實(shí)戰(zhàn)案例里會詳細(xì)展開。4. 智能指針編譯期賬本不夠用的時(shí)候4.1 Box、Rc、Arc、RefCell 各自解決什么問題所有權(quán)的默認(rèn)模型是單一所有者加獨(dú)占可變這個(gè)模型覆蓋了大部分場景但確實(shí)有幾類需求它表達(dá)不了需要在堆上分配且大小在編譯期未知的遞歸類型、需要多個(gè)所有者共享同一份數(shù)據(jù)、需要在只有不可變引用的前提下修改內(nèi)容。這三種需求分別對應(yīng)Box、Rc/Arc、Cell/RefCell。類型所有權(quán)模型線程安全運(yùn)行時(shí)開銷典型場景BoxT獨(dú)占堆分配取決于 T一次分配遞歸結(jié)構(gòu)、trait 對象RcT共享非原子計(jì)數(shù)否每次克隆加減一單線程共享只讀數(shù)據(jù)ArcT共享原子計(jì)數(shù)是T: SendSync原子操作比 Rc 慢多線程共享CellT內(nèi)部可變按值替換否幾乎為零小 Copy 類型的可變狀態(tài)RefCellT內(nèi)部可變運(yùn)行時(shí)借用檢查否借用標(biāo)志位增減需要在 self 里改內(nèi)容選型的順序我一般是這樣的先問是不是遞歸類型或需要 trait 對象是就上Box再問是不是真的需要多個(gè)所有者如果只是讀取共享用Arc包只讀數(shù)據(jù)就夠了別急著上RefCell最后才問是不是需要在不可變引用下修改需要才用RefCell。很多人一上來就寫RcRefCellT其實(shí)八成場景用RcT或者干脆傳引用就能解決白白引入了運(yùn)行時(shí)開銷和 panic 風(fēng)險(xiǎn)。4.2 Rc 加 RefCell 的代價(jià)具體在哪RcT的每次clone都要對引用計(jì)數(shù)做一次加一每次drop做一次減一減到零才釋放。這些操作在單線程里是普通的整數(shù)加減開銷很小但不為零。RefCellT則維護(hù)一個(gè)借用計(jì)數(shù)器borrow()時(shí)檢查當(dāng)前有沒有可變借用有就 panicborrow_mut()時(shí)檢查計(jì)數(shù)器是不是零不是零也 panic。這兩個(gè)檢查都是運(yùn)行時(shí)分支編譯器沒法優(yōu)化掉。更需要注意的是循環(huán)引用導(dǎo)致的內(nèi)存泄漏。兩個(gè)Rc互相指向引用計(jì)數(shù)永遠(yuǎn)不會歸零內(nèi)存就漏了。標(biāo)準(zhǔn)解法是把其中一個(gè)方向改成Weakuse std::cell::RefCell; use std::rc::{Rc, Weak}; struct Node { value: i32, next: OptionRcRefCellNode, prev: OptionWeakRefCellNode, // 用 Weak 打破環(huán) } fn main() { let a Rc::new(RefCell::new(Node { value: 1, next: None, prev: None })); let b Rc::new(RefCell::new(Node { value: 2, next: None, prev: Some(Rc::downgrade(a)) })); a.borrow_mut().next Some(Rc::clone(b)); println!(a 的強(qiáng)引用數(shù): {}, Rc::strong_count(a)); println!(a 的弱引用數(shù): {}, Rc::weak_count(a)); }Weak不增加強(qiáng)引用計(jì)數(shù)升級成Rc的時(shí)候要調(diào)upgrade()返回Option因?yàn)槟繕?biāo)可能已經(jīng)被釋放了。這個(gè)模式在雙向鏈表、樹結(jié)構(gòu)里都會用到我建議只要結(jié)構(gòu)里出現(xiàn)“指回去”的邊就默認(rèn)用Weak不要等到內(nèi)存漲上去才回頭改。4.3 有時(shí)候該退一步換數(shù)據(jù)結(jié)構(gòu)而不是堆智能指針這是我踩過的最大的一個(gè)坑。早期寫一個(gè)圖結(jié)構(gòu)的處理邏輯習(xí)慣性地用RcRefCellNode表示每個(gè)節(jié)點(diǎn)節(jié)點(diǎn)之間互相引用。代碼能跑但性能很差而且一旦涉及并發(fā)就完全沒法用因?yàn)镽c根本不是Send。后來改成用VecNode存所有節(jié)點(diǎn)節(jié)點(diǎn)之間用usize索引互相引用性能提升非常明顯代碼也短了。struct Graph { nodes: VecNode, } struct Node { edges: Vecusize, // 索引而不是引用 }索引方案的代價(jià)是你得自己保證索引有效刪節(jié)點(diǎn)的時(shí)候要處理懸空索引。但它換來的是連續(xù)的堆布局、零引用計(jì)數(shù)開銷、天然的Send Sync而且序列化也簡單得多。我現(xiàn)在的判斷標(biāo)準(zhǔn)是如果一個(gè)數(shù)據(jù)結(jié)構(gòu)里RcRefCell出現(xiàn)超過兩處就該停下來想想是不是該用索引或者 arena 了。5. 一個(gè)真實(shí)場景的重構(gòu)從編譯不過到跑得穩(wěn)5.1 需求解析文本并緩存字段假設(shè)要寫一個(gè)小模塊從多行文本里解析出鍵值對緩存起來供后續(xù)查詢。第一版我圖省事直接讓結(jié)構(gòu)體持有輸入的切片struct Configa { entries: Vec(a str, a str), } impla Configa { fn parse(input: a str) - Self { let mut entries Vec::new(); for line in input.lines() { if let Some((k, v)) line.split_once() { entries.push((k.trim(), v.trim())); } } Config { entries } } fn get(self, key: str) - Optiona str { self.entries.iter().find(|(k, _)| *k key).map(|(_, v)| *v) } }這段代碼能編譯get返回的引用直接指向原始輸入零拷貝速度很快。問題出在調(diào)用方那邊一旦把input的所有權(quán)交出去或者input是函數(shù)內(nèi)部臨時(shí)構(gòu)造的String就出事了。5.2 第一版在真實(shí)調(diào)用鏈里崩了調(diào)用方大概是這樣的fn load() - Configstatic { let content std::fs::read_to_string(config.txt).unwrap(); Config::parse(content) // 報(bào)錯(cuò)返回引用了局部變量 }編譯器報(bào) E0515說不能返回指向局部變量的引用。這不是編譯器的刁難content在函數(shù)結(jié)束時(shí)就 drop 了返回的Config里那些指針會立刻變成懸垂指針。如果這段代碼在 C 里寫編譯能過運(yùn)行時(shí)讀到的就是垃圾數(shù)據(jù)而且可能好幾個(gè)月都不出問題直到某次內(nèi)存布局變化才突然炸。第二版我把結(jié)構(gòu)體改成持有Stringstruct Config { entries: Vec(String, String), } impl Config { fn parse(input: str) - Self { let mut entries Vec::new(); for line in input.lines() { if let Some((k, v)) line.split_once() { entries.push((k.trim().to_string(), v.trim().to_string())); } } Config { entries } } fn get(self, key: str) - Optionstr { self.entries.iter().find(|(k, _)| k key).map(|(_, v)| v.as_str()) } }這樣寫能跨函數(shù)傳遞、能存進(jìn)集合、能放進(jìn)Arc里共享代價(jià)是每個(gè)鍵值對兩次堆分配。對于配置文件這種一次性加載、長期駐留的場景這個(gè)代價(jià)完全值得。但如果是解析大文件做流式處理每行兩次分配就有點(diǎn)浪費(fèi)了。5.3 第三版用 Cow 做折中Cow寫時(shí)克隆是這兩者之間的折中方案。它在不需要修改的時(shí)候借用原始數(shù)據(jù)需要修改的時(shí)候才分配use std::borrow::Cow; enum Entrya { Borrowed(a str), Owned(String), } fn normalize(s: str) - Cow_, str { if s.contains(\t) { Cow::Owned(s.replace(\t, )) } else { Cow::Borrowed(s) } }Cowa, str是標(biāo)準(zhǔn)庫提供的枚舉只有Borrowed和Owned兩個(gè)變體。它的好處是調(diào)用方不用關(guān)心底層到底是借用還是擁有用.as_ref()或Deref就能當(dāng)str用。壞處是它仍然帶著生命周期參數(shù)跨函數(shù)邊界的時(shí)候該傳播還得傳播而且枚舉本身占的??臻g比單純的str大具體多大可以用size_of實(shí)測一下不同版本和優(yōu)化下會有差異。我現(xiàn)在的選擇順序是數(shù)據(jù)生命周期短、調(diào)用鏈淺用str加生命周期數(shù)據(jù)要被長期持有、跨線程傳遞用String兩者之間搖擺不定的中型場景用Cow。這個(gè)順序不是教條但你照著走能少走彎路。6. 高頻報(bào)錯(cuò)與排查速查6.1 錯(cuò)誤碼對照表被借用檢查器攔住的時(shí)候先看錯(cuò)誤碼再看提示里的“誰的借用還沒結(jié)束”。下面這張表是我整理的高頻錯(cuò)誤基本上覆蓋了日常八成的情況。錯(cuò)誤碼含義典型改法E0382使用了已經(jīng) move 的值改傳引用或在轉(zhuǎn)移前 cloneE0499同一作用域內(nèi)兩次可變借用拆分成兩個(gè)階段或用索引代替引用E0502可變借用與不可變借用沖突先讀后寫或縮短不可變借用的生命周期E0505借用還沒結(jié)束就要 move讓借用先結(jié)束再 moveE0515返回了局部變量的引用返回?fù)碛兴袡?quán)的類型E0597被借用的值活不到那么久調(diào)整作用域順序或改為擁有E0716臨時(shí)值在借用期間被釋放先用 let 綁定成變量再借用E0106缺少生命周期標(biāo)注按省略規(guī)則補(bǔ)上或改成擁有類型E0716 值得單獨(dú)提一句很多人寫過類似的代碼然后一臉茫然fn main() { // let s String::from(hello).as_str(); // 報(bào)錯(cuò) E0716 let tmp String::from(hello); // 先綁定成變量 let s tmp.as_str(); // 再借用 println!({}, s); }原因是String::from(hello)產(chǎn)生的臨時(shí)值在這一行結(jié)束時(shí)就被 drop 了as_str()借出來的引用立刻懸垂。先綁定到tmp之后tmp活到作用域結(jié)束借用才合法。這類問題的排查思路很統(tǒng)一看那個(gè)被借用的值是不是臨時(shí)值是就給它一個(gè)名字。6.2 排查順序先找誰借了誰再看誰要活多久我處理借用錯(cuò)誤的固定流程是這樣的。第一步看錯(cuò)誤提示里點(diǎn)名的變量確認(rèn)是“值被 move 了”還是“借用沖突”。第二步如果是借用沖突從報(bào)錯(cuò)位置往上找找最后一個(gè)使用這個(gè)引用的地方那里就是借用結(jié)束的位置。第三步如果想讓借用提前結(jié)束就把后面的寫操作挪到那之后或者把讀的結(jié)果先取出來存成獨(dú)立的值。第四步如果怎么調(diào)都不行說明數(shù)據(jù)結(jié)構(gòu)的所有權(quán)模型設(shè)計(jì)有問題考慮換成索引、Rc或者擁有類型。這個(gè)流程里第三步最常用。舉一個(gè)我經(jīng)常遇到的場景需要在HashMap里查一個(gè)值然后修改它use std::collections::HashMap; fn main() { let mut map: HashMapString, i32 HashMap::new(); map.insert(a.to_string(), 1); // let v map.get(a).unwrap(); // map.insert(b.to_string(), 2); // 報(bào)錯(cuò) E0502 // println!({}, v); let v map.get(a).copied().unwrap_or(0); // 先取值結(jié)束借用 map.insert(b.to_string(), 2); println!({}, v); }copied()把Optioni32變成Optioni32借用當(dāng)場結(jié)束后面的插入就自由了。這個(gè)技巧在處理哈希表、緩存的時(shí)候特別好用我基本養(yǎng)成了習(xí)慣只要借出來的值很小且 Copy先拷貝再用。6.3 幾條踩出來的實(shí)操心得第一別怕加花括號。雖然 NLL 已經(jīng)聰明很多但在某些復(fù)雜表達(dá)式里顯式劃一個(gè)作用域讓借用提前結(jié)束比絞盡腦汁調(diào)整順序省事得多。第二clone()不是洪水猛獸在冷路徑上用 clone 換代碼清晰度是完全劃算的我反對的是在熱循環(huán)里無意識地 clone。第三遇到RcRefCellT的borrow_mutpanic先找有沒有在同一段代碼里同時(shí)持有兩個(gè)借用尤其是鏈?zhǔn)秸{(diào)用里臨時(shí)值還沒釋放的情況把中間結(jié)果用let綁定出來往往就好了。第四函數(shù)簽名優(yōu)先用借用只有在確實(shí)需要保存或跨線程的時(shí)候才用擁有類型這條規(guī)則能讓你的模塊接口干凈很多。第五如果一段邏輯里到處都是unsafe或者反射式的類型轉(zhuǎn)換那多半不是所有權(quán)的問題是數(shù)據(jù)結(jié)構(gòu)選錯(cuò)了回頭看看第 4.3 節(jié)。關(guān)于內(nèi)存管理我個(gè)人在實(shí)際操作中最深的一點(diǎn)體會是所有權(quán)系統(tǒng)真正改變的不是你寫代碼的語法而是你設(shè)計(jì)數(shù)據(jù)結(jié)構(gòu)的方式。寫 C 的時(shí)候我會自然地想“這塊內(nèi)存誰 free”寫 Java 的時(shí)候基本不想寫 Rust 之后我會在動(dòng)手寫第一行之前就想清楚“這個(gè)值的生命周期有多長、誰能改它、要不要共享”。這個(gè)思考前置的過程一開始很別扭習(xí)慣之后反而省掉了大量調(diào)試時(shí)間因?yàn)楹芏鄦栴}在敲代碼的時(shí)候就已經(jīng)被逼著想明白了。
返回列表
PREV
查看更多資訊
NEXT
返回資訊列表
99爱在线| 99这里只有精品视频免费| 激情综合五| 五月婷婷六月丁香首页| 亚洲六月色| 日本爆乳片手机在线播放| 亚洲综合五月天婷婷丁香| 99噜噜噜在线播放| 日本色道视频网站| 欧美三日本三级少妇三99| 九九热九九热精品| 五月婷婷免费在线| 久久婷婷色色| 182TV大香蕉| 丁香五月成人| 亚洲综合五月天| 丁香五月激情婷婷婷婷在线观看| 色青五月天| 婷婷五月天Av| 大香AV| 老师的粉嫩小又紧水又多A片视频 粉嫩AV久久一区二区三区 | 九九九九毛片| 久久 婷婷 五月天| 超碰在线9| 亚洲最大五月天成人网| 一级A片天天操夜夜操| 67194成I人在线观看线路1| 国产九月婷婷| 精品九九久久| 一区二区三区四区牛| 校花娇喘呻吟校长陈若雪视频 | AV操一操| 日韩在线一级| 激情五月色综合网| 色婷天天| 婷婷五月丁香久久| a在线观看| 五月丁香啪。| 五月天伊人综合| 激情网色五月| 大香蕉九九操| 97人人操在线| 日日干日日色| 欧美色小说婷婷| 婷婷五月丁香在线观看| WWW.夜夜| 射区导航| 色色色色网| 日本三级中文字幕| 人妻av在线| 一本色道久久综合狠狠躁小说| www.精品99| 99精品一二三四视频| 亚洲成人av在线播放| 99精品免费欧美小视频| 五月婷婷深深爱| 99这里有精品| 天天影院色| 色播综合| 日本黄 色 片| 91xxxx九色| 久七香蕉| 青草性爱视频| 深爱激清网| 婷婷丁香五月亚洲| 99在线精品观看99| 久久婷婷七月丁香| 婷婷五月综合网| 亚洲无线视频| 久久机热这里只有 | 成人亚洲精品| 婷婷五点亚洲| 大香网伊人久久综合| 久草五月天| 99热综合| 综合 蜜月 婷婷| 五月亭久久无码视频| 性爱网六月丁香| 热五月婷婷| 97色热| 激情婷婷色色| 人妻VideOssS人妻高清| 91久操| 99热这里是精品| 熟妇人妻中文字幕无码老熟妇| 精品一区久热| 国产片天天爽夜夜爽| 99视频精品全部免费观看| 婷婷五月天欧美图片在线播放电驴| 五月婷视屏在线观看| 五月色综合网| 激情五月天婷婷| 婷婷99视频在线| 啪啪五月婷婷| 婷婷久久夜| 综合网亚洲| 六月丁香av| 国产成人AV| 激情五月份婷婷| 婷婷丁香人妻天久久| 黄页大全十八禁| 色在线99| 玖玖综合色区在线观看| 97五月天婷婷午夜| 99热18| 大香蕉AV电影在线| 开心五月激情站| 亚洲综合另类| 成人 AV播放| 亚洲国产婷婷色五月| 性生活视频98791| 色五月天丁香婷婷| 激情五月综合久久| 无码操B| 国产AV一区二区三区最新精品| 9久久久| 99rewww| 热久久这里只有精品| 五月婷婷六月激情| 丁香五月AV在线| 五月丁香婷婷网在线在线| 成人无码髙潮喷水A片| 亚洲顶级VA在线观看-高清完整版在线影院观看-S022AV | 97在线刺激| 日日操,夜夜撸| 99在线观看视频| WWW.亚洲无码| 天天色天天舔天天爱天天爽 | 欧美成人精品A片免费一区99| 欧美久久婷婷| 99在线视频精品| 日日操夜夜操中国无码| 啪啪亚洲综合| 色八戒操婷婷| 婷婷五月色播放| 亚洲V国产V欧美V久久久久久| 激情五月天啪啪| 婷婷五月天六点丁香五月| 国产精品成人AV在线观看春天| 另类图片激情五月| 91久久久久久| 五月天婷综合网站| 国产小精品| 色狠狠色| 97婷婷色| 亚洲婷婷丁香五月视频| 97色精品视频 | 激情综合五月丁香| 婷婷久久五月| 五月婷婷丁香色播网| 国内一级片| 亚洲综合网激情五月天| 666555。COm毛片| 天天婷婷天天| 婷婷福利影院| 综合色色婷婷| 欧日韩AV| 七七色综合| 人妻操在线看| 欧美伊人9| 停婷丁五月在线| 超碰成人AV| 色婷婷色五月天| 五月丁香婷婷狠狠操| 99热精品综合| 日韩情色在线观看| 色情综合网| 91一起操| 99福利视频导航| 丁香六月亚洲综合| 91操片| 97色干| 久久99综合| 丁香五月在线观看| 99热这里只有精品无码| 99在线资源| 婷婷九九| 色婷激情网| 超碰无码老师| 婷婷婷婷色| 国产日产成人亚洲欧美国产VA| 色色亚洲| 五月天色五月| 久热这里只有精品在线观看| 97偷拍在线视频| 182TV大香蕉| 婷婷天堂综合| 超碰国产一区| 五月丁香六月激情| 激情五月婷婷开心网| 在线你懂的亚洲欧| 国内久久婷婷| 五月丁香久久| 天天爽天天干| 人人色AV| 色色色999| 无码人妻少妇色欲AV一区二区| 六月色五月天天婷婷| 色色97丁香婷婷五月天| 亚洲综合九九| 91精品久久久久久久久| www.六月丁香看AV| 激情久久四色| 午夜成人网站在线观看| www.婷婷久久五月天| 俺也去在线久久精品23欧美综合视频网站,丰满人妻一区二区三区在线视频53,丰满 | 天天干,夜夜爽| 色日本网| 五月婷婷六月丁香综合视频在线| 五月丁香亭亭操逼| 五月丁香中文婷婷中文| 婷婷中文字幕网站| 国产毛片精品一区二区色欲黄A片| 亚洲aV写真天天综合网久久| 欧美色色色色色色色色色色影视| 国产97色在线 | 日韩| 九九热超碰| 日本97久久久精品| 99久久久精品| 日韩一级| 亚洲黄色网址| 国产又爽又猛又粗的视频A片| 99热1| 五月天伊人手机在线播放AV| 六月丁香深深爱| 色婷婷国产精品综合在线观看| 青青久在线视频免费观看| 久久停停超碰| 大香蕉网站,大香蕉综合| 亚洲色综合性| 天天干、天天日日| 天天干天天操天天上| 欧洲亚洲免费视频9 | 再次出发二| 色天使色婷婷| 五月丁香大相交| 久久男人网婷婷| 日本天天色| 97视频91| 六月丁香啪啪啪| 玖玖爱综合网| 97九色| 伊人在线视频| 久久久婷婷五月亚洲97号色| 91久久电影| 欧美日韩AAA| 思思热在线精品视频网站| 色婷婷基地在线| 五月婷婷综合久久| 五月天婷婷综合久久| 久久婷婷丁香| 久热人妻| 五月天无码视屏播放| 亚洲综合视频天天精品| 婷婷久久夜| 丁香午月AV中文字幕| 7超碰自拍| 久久久五月五丁香| 99热 在线观看| 激情综合播播| 另类小说五月天激情| 色婷婷欧美在线| 九九热这里只有精品556| 五月天婷婷色五月天| 久久丁香五月综合六月激情红杏视频| 丁香五月婷婷啪| 五月天婷婷六月激情网| 色婷婷五月亚洲| 丁香色五月婷婷91桃色| 99视频精品全部观看10| 成人电影一区| 国产成人精品一区二三区熟女在线 | 五月丁花色综合网| 五月性色| 亚洲1区| 少妇大叫太大太粗太爽了A片| www.狠狠| 秋霞网在线免费基地五月婷婷丁香| 色婷婷精品视频在线播放| 综合久久8| 99人人精品| 色婷婷久久久| 五月丁香狠狠| 另类小说五月天| 开心五月激情网| 五月丁小婷婷激情四射| 久久丁香五月| 色婷婷香蕉丁丁网| 91热久久| 天天久久九九| 五月激情丁香六月狠狠干| 婷婷五六日| 新精品99| 91丨九色丨高潮丰满日本| 99精品人人| 色色五月婷婷| 99操逼| 在线成人网址| 任你弄在线视频免费| 射久久丁香五月| 激情五月深爱五月| 婷婷月综合| 狠狠色综合网| 亚洲无码yw| 人人爽在线视频综合网| 色五月大| 91妻人人爽人人看片| 五月天丁香婷婷社区| 中文网AV| 五月丁香激情综合啪啪| 碰人人97| 五月丁香 啪啪啪| 97碰碰视频在线观看| 日韩av变天就操逼不卡区| 国产肏屄大片| 日本天堂网站99| 色99日韩| 色婷婷五月天在线观看| 日日夜夜九九| 国产日批视频| 26uuu国产| 变态另类色图 | 色婷婷久久7777| 久久五月天色婷婷| 97人人射| 人妻激情综合| 操逼巨乳91| 五月婷婷影视| 丁香六月婷婷综合网| 99久久精品国产色欲| 中文字幕 中文字幕明步| 六月婷婷久久| 丁香六月激情综合| 丁香婷婷久久综合在线| 俺去啦综合网| 婷婷五月综合性爱| 五月开心激情网| a久久| 五月天婷婷爱| 伊人婷婷大香蕉| 天天透天天干| 五月天色丁香| 婷婷色在线视频| 另类激情五月天| 99人妻碰碰久久久禁片| 九月婷婷丁香| 国产精品久久久久久喷浆| 亚洲国产成人综合| 丁香六月婷婷| 色播五月婷婷综合| 性做爰1一7伦| 激情综合网,婷婷五月天| 久热这里只有| 婷婷激情五月天激情在线| 级情九色| 色五月综合婷婷久久综合婷婷久久综合婷婷久久综合婷婷久久 | 超碰成人电影| 婷婷五月天色播| 综合久| 久99久在线| WWW.99视频| 亚洲乱码w在线观看| 狠狠色婷婷丁香五月| 亚洲人成人五月天| 69色婷婷| 日韩一级片| 亚洲激情婷婷| 日韩成人综合网| 色综合爽| 99色在线观看视频者| 丁香丝袜五月| 五月天婷婷丁香花| 久久久婷| 激情五月婷婷伊人| 人人看人人97| se99视频| 噜噜噜色噜噜| 亚洲精品在线视频| 五月婷婷丁香五月| 婷婷色Av| 六月丁香中文字幕| 桃色五月天| 五月久久亚洲| 久操干| 丁香六月啪| 婷婷欧美色| 538在线精品| 无码色色| 99精品国产在热久久| 五月丁香婷婷综合| 五月丁香性| www.狠狠| 婷婷久久爱| 免费AV在线| 看婷婷五月天网| 欧美大片| 色私五月婷婷| 99热精这里只有精品| 伊人影院久久网| 97操在线视频| 五月婷导航| 婷婷综合97| 狠狠色综合网| 亚洲乱码在线观看| 丁香婷婷六月在线资源观看| 婷婷伊人网| 国产精品色情AAAAA片软件| 婷婷五月花丁香| AV在线观看网站| 国产人妻777人伦精品HD| 六月色婷婷| 99rewww| 色五月婷婷天堂| 欧美这里只有精品| 亚洲精品色| 九九精品这里只有| 人人干99| 97人人操人人操人人操人人| 人妻体体内射精一区二区 | 中文字幕精品推荐免费在线观| 丁香五月欧美激情| 五月丁香综合在线| 天天狠狠色噜噜| 九九热欧美| 97碰91| 六月丁丁香| 天天射影院| 婷婷中文字幕版| 日韩成人中文字幕| 成人色图情色成人网 www.5b5b5bcom 五月天 | 五月天丁香成人社| 激情五月婷婷六月丁香| www激情网| wwwss在线观看| 五月婷婷精品视频| 五月成人丁香av91| 国产又粗又大又爽又黄| 五月婷婷六月色| 久久99综合网| 大天天伊人| 999影院成人在线影院| www.激情五月天.com| 五月天伊人综合| 天堂网操| 久久婷婷电影| 超碰色人妾| 五月丁香综合色婷婷| 大香蕉520| 丁香婷婷九月| 99色干| 噜噜狠狠色综合久| 偷偷操99| 久久HD| 五月激情婷婷综合| 超碰人人射| 激情开心五月天| www.五月.com| 色欧美影院| 亚洲天天| 亚洲人人操| 色五月婷婷在线| 俺去也五月天婷婷| 精品色色| 四色永久成人网站| 亚洲综合五月天婷婷丁香| 五月亭亭直播| 国产精品一区在线观看你懂的| 人人干av| 最近韩国日本免费高清观看| 亚洲三A| 日韩精品一区二区三区,四区,五区视频| 丁香五月婷婷基地| 成人草榴视频| 亚洲无码九九九| 日韩激情网站| 97人人操在线| 色色色视频| 久久 这里只有精品1| 欧美视频在线观看噜噜| 99色精品| 九九色婷婷| 狠狠狠狠狠| 国产全是老熟女太爽了| WWW.五月com| 色爱综合五月| 九九综合视频在线观看| 婷婷五月天视频小说| 人人人人人人人草| 久久综合五月天| 丁香六月婷婷色XXXXX| 天天爽天天操| 中文字幕av网站| 玖玖五月丁香| 99热精品网| www.激情五月天com| 婷婷五月天狠狠搞干| 另类小说色婷婷| 色停停香蕉视频| 婷婷六月天| 日本黄色一级| 色色爽爽天天| 五月激情婷婷开心| 丁香五月婷久久| 666555。COm毛片| 久久婷婷东京热大香樵| 梁铮版《蜘蛛女侠》在线| 激情综合六月| 色色综合网站| 伊人激情综合| 欧美va亚洲va| 丁香五月婷婷网| 激情婷婷五月天| AV在线不卡网站| 大香网伊人久久综合| 色五月婷婷久久大| 狠狠插狠狠操| 97久久五月丁香婷婷| 婷婷五月激情基地| 美欧日韩国产成人在战| 91丨九色丨国产| 99久热在线精品| 色婷婷综合网站| 激情久久久| 婷婷五月天丁香久久| 婷婷激情肏屄网| 99爱视频在线观看这里只有精品| 久操婷婷| 久婷婷| 色婷婷小说| 可以免费观看的av| 中文色婷婷| 这里只有精彩视| 99热6精品| 久久久27操| 五月天黄色激情小说| 激情视频网址| 九热视频在线精品15| 韩国久久少妇视屏| 四LLL少妇BBBB槡BBBB| 97超碰人人操| 五月丁香色综合| 九九九九九九热| 中文字幕+乱码+中文字幕在线观看| 超碰国产AV| 九九成年视频| 亭亭五月天黑人2014| 丁香九月婷婷| 五月激情五月丁香| 久热这里只有精品6| 婷婷五月天网址| 久久一热| 狠狠 久久| 天天插天天| 一本大道伊人AV久久综合| 色就是色婷婷五月亚洲激情| 超碰在线国产| 婷婷五月天影院| 99热综合在线| 中文字幕,综合,91| 五月丁香六月婷婷激情视频在线观看免费| 影音先锋男士资源网一区| 伊人婷婷激情| 婷婷五月天综合亚洲| www·五月天| av亚洲国产小电影| 开心五月婷婷在线视频免费观看| 国产乱妇无乱码大黄AA片| 久久婷婷成人视频| 极品人妻VIDEOSSS人妻| 亚洲 无码 中文字幕 中出| 八戒青柠影视剧在线观看| 久色成人| 日本综合99| 夜夜综合色| 国产色色小草视频| 99免费视频| 国产日韩av片| 六月激情婷婷| 婷婷六月丁香1| 国外亚洲成AV人片在线观看| 九九热精品视频九九| 奇米色大香蕉| 99热在线看片| 久久五月天精品视频| 九九99精品视频在线观看| 婷婷五月激情六月丁香| 丁香五月婷婷欧美性爱| 99国产视频网| www999日韩精品| 五月成人网站| 激情五月视频| 九九精品99久久久| 五月开心久久| 五月婷婷啪啪网| avv在线| 99热综合| 丁香婷婷十月| 婷婷天堂综合| 香蕉AV777XXX色综合一区| 操操操AV| 色啪影院| 99色人| 亚洲综合另类| 久久视频这里都是精品| 丁香九月综合在线| 99成人| 人妻久久久久久久久久久| 97色热| 性做爰1一7伦| 操日视频| 亚洲成人乱码av网站| 婷婷99狠狠躁天天躁中文| 久久九九国产精品怡红院| av人人操| 欧亚色色| 久久99精品久久久久久三级| 综合五月天| 五月天国产| 五月丁香婷婷综合在线| 婷婷五月天大香蕉| WWW.久久.COM| 色五月激情婷婷| 色婷婷成人做爰A片免费看网站| 国产成人AV在线播放| Av性爱网| 99啪啪网| 久久5 9视频免费观看| 亚洲美女高潮久久久久久69| 丁香婷在线| 五月丁香六月激情综合网| 二区成人视频| 国产FREESEXVIDEOS性中国 | 在线观看的av| 丁香五月天激情四射网络不好| 人人爽天天爽| 五月丁香啪啪婷婷| www天天爽| WWW.桔色成人.COM入口| 日本99视频| 日韩视频女神99| 91肏肏肏| 亚洲V国产V欧美V久久久久久| 99九九在线观看免费| 五月丁香激情深爱婷婷| 亚洲婷婷丁香五月天激情小说| 色色色在线| 伊人大香久久| 97爱艹婷婷开心丁香激情综合| 五月天婷婷无码| 免费啪啪亚州视频| 亚洲va在线∨a天堂va欧美va| 五月天自拍网| 开心深爱五月天| 久久99婷婷| 久久精品综合色| 亚洲色区17| 丁香六月天婷婷色| 老妇六区| 久久99最新地址| 大地资源色婷婷视频在线 | 五月久久亚洲| 狠狠色五月| 婷五月丁香| 免费99情趣网视频| 日本人妻丁香婷婷久久寝取熟女五月| 好好干Av| 丁香五月婷婷五月天在线| 超碰99在线观看| www.五月婷婷| 婷婷丁香五月亚洲欧美| 久久这里都是精品免费| 中海油常州环保涂料有限公司| 丁香五月天网站| 久99视频| 五月丁香怕啪啪| 操笔无码| 怡红院院久久| 五月激情网站| 婷婷深爱五月天| 激情综合网色播五月| 伊人玖玖婷婷| 国产成人网址| 婷婷五月在线视频| 操操综合网婷婷| 色综合女人99| 国产九九一区二区三区| www.99婷婷| 丁香六月婷婷久久综合八月| 青草性爱视频| 色播婷婷五月天| 思思热99热| 99riAv1国产在线观看| 99热日本| 极品人妻VIDEOSSS人妻| 葵花AV在线| 丁香激情四射| 久热2025无码| va婷婷| 在线另类视频| 午夜少妇在线观看视频| 亚洲精品九九| 成人 在线 日韩| 电影蜘蛛女| 人人爽亚洲| 丁香 久久| 激情五月天视频| 熟女强人妻一区二区三区四区无| www.久久9| 婷婷97| 久久66精品| 激情五月婷黄版| 99色色网| 牛牛色av| 人人澡天天色天天做| 天天色天天色天天色天天色天天色| 五月婷婷五月天在线 | 丁香婷婷五色月| 色色色热| 国产做爰视频免费播放| 精品亚洲国产成AV人片传媒| 日日操夜夜爽天天天| 激情五月天偷拍综合网| 婷婷丁香六月| 97极品在线| 激情激情激情网| 久久丁香五月| 91人妻九色大屁股| 99视频超级精品| 五月丁香操亭亭网| 99视频自拍| 色婷婷四色| 五月丁香在线国产| 色噜噜综合网| 九九九九中文字幕| 激情婷婷丁香五月| 91精品久久久久久| 中文字幕婷婷在线| 激情婷婷狠狠干| 97人人操人人爽| 丁香婷婷老司机久操| 思思热99er在线视频| 五月丁香激情综合| 亚韩精品视频1区| 人妻久久久久久久久妻久久久久久久久 | 99精品久久久久久久| 亚洲婷婷激情888精品久| 五月激情视频| 铁牛TV人妻| 深爱激情六月| 欧美槡BBBB槡BBB少妇| 日本片日本片祼观看网站在线看中文版网页在线看 | 新精品99| 色色三级视频| 婷婷丁香六月影视| 色婷婷六月| 九九热99免费视频| 五月天色婷婷综合| 一区二区你懂的| 五月丁香在线偷拍视频| 国产69久久久欧美黑人A片| 五月婷婷六月丁香综合| 99.N在线视频| 婷婷第一页| 日韩99色99| 中文字幕婷婷9月天| 情欲综合网| 东京热免费视频| 综合天天综合| 丁香五月Av| www.激情| 99视频精品在线| www.久久99| 狠狠干婷婷| 996热| 亚州操人在线视频| 婷婷在线播放av| 婷婷五月六月| 亚洲无码成人网| 丁香五月天电影| 婷婷在线播放av| 可以看的av| 丁香六月 婷婷六月| 天天爱天天爽| 视色网在线播放| 国产暴力强伦轩1区二区小说| 九九热再线九九视频免费在线观看 | www.色婷婷.com| 色婷婷狠狠久久YY| 天天久久狠狠色综合| 91在线日| 五月激情啪啪| 天天日天天操天天干| 五月丁香色欲| 婷婷狠狠操| 91干在线| 色婷婷五月天在线观看| 五月开心六月婷婷在线播放网站| 国产亚洲精品久久久久苍井松| 亚洲久久婷婷丁香五月天| 日韩专区五月天婷婷丁香| 五月丁香婷婷潮喷中文字幕| 99玖玖人人| 久久婷婷综| www色婷婷久久综合久色| 无码 av电影| 欧美α√| 五月丁香婷婷色| 少妇AB又爽又紧无码网站| 五月天深爱激情网| 六月久久婷婷| 激情AV| 亚洲欧州色情在线观看| 国产4P视频精品五区| www久久久| 久久 这里只有精品1| 超碰色天堂| 色情婷婷五月天| 五月丁香婷婷中文网| 丁香玖玖视频大全| 五月丁香啪啪网| 五月丁香啪啪伦理电影| 九九碰九九爱97超碰| chaopengdaxiangjiao| 五月亭亭开心网| 五月天天天综合| 七七久久婷婷| 狠狠色成人影片| 久热网站| 激情五月黄色小说| 综合激情sV| 色婷五月天| 五月丁香婷婷欧美| 婷婷五月激情丁香激情| 久久激情天堂| 国产性爱在线| 久久性爱视频| 狠狠色噜噜| 大功率国产在线| 丁香熟女乱| 99热只有| 99日本黄站| 久久这里有精品在线观看| 久久人人看| 色婷婷影视99| 青青青在线视频国产| 婷婷成人五月天| 国产熟女日日骚五月丁香爱| 色情五月综合婷婷| 久久婷婷东京热大香樵| 少妇性BBB搡BBB爽爽爽电影| 五月婷婷天堂| 综合久久人妻| 丁香六月天婷婷色| 99免费综合网| 色一情一乱一乱91Av| 日韩黄在免| 婷婷五月天小说| 午夜九九九九九九九九九九九九九| 九九热短视频在线观看| 99热乎| 97在线/亚洲| 超碰A V在线| 成人国产欧美大片一区| 99热8| 五月天色综合| 色色色色热| 色综合色综合网| 色五月 激情婷婷 综合五月天| 激情综合区| 婷婷大乡焦噜噜| 日本人妻久久| 六月色丁香婷婷| 99re6在线视频精品免费| 日韩1区2区| 影音先锋一区二区三区| 久9视频免费播放| 丁香色婷婷五月天| 丁香六月无码播放| 激情五月婷婷色播网| 婷婷色日本| 丁香五月天婷婷久久| 婷婷久久午夜网| 久久色在线视频| 开心五月婷婷五月| 97色色色色| AV激情五月| 五月天无码| 久久99热这里只有| xxxx五月| 五月婷婷和六月| 婷婷五月天伦理| 婷婷色香六月综合激情| 99人这里只有精品| 激情六月五月婷婷综合网| 亚洲色五月天是什么| 婷婷五月天直播| 婷婷综合成人五月天| 97色色色色色色色色色色色色色| 思思久久96热在精品国产,| AV美美午夜| 激情五月五月五月婷婷| 精品三区影院| www.五月.com| 91九色精品| 婷婷丁香成人| 欧美日韩99| 熟妇人妻中文字幕无码老熟妇 | 婷五月天| 9福利性视频欧美| 日韩婷婷| 丁香五月六月婷婷自拍| 九九热这里只有精品31| 九九婷婷网五月天| 成人国产综合| 婷婷97| 色综合99无码 | 丁香六月五月婷婷| 亚洲综合五月天| 婷婷色网站| 九九香蕉网| 婷婷丁香91综合| 欧美成人日韩| 天天色综和网| 丁香五月人妻熟女| 天天弄天天操| 五月丁香六月欧美综合网站| 色一情一乱一伦一区二区三区| 九九99精品视品| 67194中文字幕| 亚洲精品色色| 五月丁香在线婷婷美女| 色色五月天丁香婷婷| www.狠狠| 九 九九九AV| 超碰激情网| 亚洲婷婷婷| 婷婷午夜综合| 欧美叉叉叉BBB网站| 99ri国产精品| VA婷婷| 九九热在线视频观看| 婷婷香五月天| 亚洲性爱AV| 久久婷婷五月天激情新地址| 99er久久| 激情综合网五月| 玖玖九九9999在线观看视频精品| 97色婷婷成人综合在线观看| 五月婷婷深爱六月| 久9久9久9久9久9久9| 亚洲成人无码专区| 亚洲操逼片| 五月天深爱激情网| 99热这里只有精品4| 九97免费视频| 婷婷五月天伊人在线| 色五月婷婷五月| 国产成人精品一区二三区熟女在线| 五月亭亭色| 五月婷婷熟女| 九月激情网| 色五月美女| www.粉嫩av.com| 婷婷九月丁香| 五月丁香婷婷伊人| 五月婷俺去也| 日本五月天网站| 久久一级AV| 大香蕉久久伊人婷婷五月丁香| 26uuu精品国产| 亚洲蜜桃精久久久久久久久久久久 | 五月天国产| 涩丁香| 最新午夜理论片| 中文无码婷婷| 99五月婷| 99在线精品免费视频| 亚洲亚洲人成综合网络| 久久99久久99精品免视看婷婷| 日韩AAAAAAAAAAA片| 九九九九操逼| 亚洲视频在线观看99| 色啪影院| 中文字幕丰满人妻无码专区| 79色色色色| 伊人高清无码| 婷婷久久免费看| 久热这里| 国产99久久久| 亚洲在线综合| 97碰碰在线观看视频| 亚洲精品午夜国产va久久成人| 99ree6| 日本特黄aaaaa| 久热91| 四色综合网| 日韩视频99| 丁香色色网| 亚洲网视屏| 九九九九综合| www999日韩精品| 激情图片99| 天天综合精品| 国产精品丝| 99久久久久久www| 婷婷色在线播放| av在线免费网站| 久久超视频| 色欧美影院| 五月丁香激情综合六月涩涩爱| 色婷婷五月天久久| 91丨九色|PRNY熟妇| 午夜婷婷久久| 婷婷五月激情图片| 99久久婷婷| 亚洲视频a| 欧美色五月| 5月色亭亭视频| 亚洲情综合五月天| 五月丁香激情在线| 丁香五月激情啪啪啪| 26uuu亚洲| 日韩精品一区二区亚洲AV观看| 亚洲无码11| 91爱操| 丁香五月社区| 五月丁香久久久日婷婷久久婷婷日| 熟女人妻一区二区三区免费看 | 亚洲色婷婷视频| 涩五月丝袜婷婷| 99热99美国在线观看| 99热人人| 婷婷五月天小说| 六月丁香激情综合| 99热热热国产超碰| 日本久久精品| 五月婷婷就去色| 丁香五月欧美婷婷| 激情婷婷五月天| 天天操天天爱天天日| 三年高清大片免费观看国语| 日日操天天| 人妻aV在线| 婷婷91| 女人天堂 AV| www.婷婷六月天| 九九热精品视频在线观看| www.婷婷,com| 久久久久激情网| 婷婷五月天色色| 五月天婷婷中文字幕在线播放| 99热欧美偷拍| 婷婷综合五月| 日屌日日操日日色| 久热欧美| 婷婷五月,综合伊人| 五月婷婷六月丁香| 婷婷伊在线| 婷五月天| 日本九九九九| 婷婷五月天中文字幕| 久久久久婷婷| 人五月天婷婷喷水| 九九五月天| 丁香五月婷婷成人网| 一区视频网站| j五月香在线| 伦乱天堂| 丁香六月婷婷姐网| 色情性爱视频网址| 色婷综合| 亚洲中文字幕在线观看| 六月天婷婷| 婷婷色五月天第7色| 婷婷天堂视频| 午夜伊人大香蕉| 97碰在线视频| 亚洲色99| 亚洲激情免费久久| 丁香五月综合激情性爱| 97日韩无套内| 婷婷五月色播放| 婷婷五月丁香六月综合网| 亚洲色色图片| www,色婷婷| 9l久久久视频| 99re6在线视频精品免费| 区美毛片子| 五月天五月天成人网亭亭成人色网站| 五月开心婷婷极品激情| 大香蕉人人网| 草草女人亚洲| 五月天色色网站| 啪啪99| 天干夜夜操| 久久99久久99精品免视看婷婷| 成人午夜无码视频| 欧美、日韩、中文、制服、人妻| 99热热热99精品丁香| 婷婷五月六月| 激情综合网五月丁香| 五月天亚洲色| 激情综合色五月丁香六月亚洲| 99色色热| 999热在线视频| 成人短视频在线免费观看| 任你弄在线视频免费| 少妇2做爰HD韩国电影| 婷婷丁香五月亚洲17cao| 色色色五月婷| 五月婷婷中文字幕| 婷婷伊人久久综合| 东北婷婷五月天| 婷婷五月天激情综合婷婷五月天激情综合 | 天天摸天天舔| 五月天另类小说| 快色t v在线入口| 日日射天天射| 免费久久这里只有精品99| 综合综合色色| 欧美狠狠一在草| 丁香五月天在线观看视频| 91美女被操| 五月婷亚洲精品AV天堂| 五月丁香好婷婷A片网| 97碰免费精采视频| 婷婷五月无码| 91xxxx九色| 热热99爱爱| 丁香五月天婷婷91| 99久久新视频| 日韩伊人大香蕉| 激情宗合 激情宗合| 人人搡人人| 伊人网啪啪| 丁香伊人网| 色婷婷久久综合| 色五月天.con| 另类五月婷婷| 婷婷丁香成人在线视频| 99人妻碰碰久久久禁片| 五月婷婷综合在线视频小说| 天天爽天天做| 俺也去在线视频| 五月天亚洲色| 综合色影| 五月丁香婷婷色| 久久久久人妻| 国产亚洲精品久久久久苍井松| 少妇出轨做爰高潮A片| 97碰碰久久| 91视频久久久| 色欲丁香| 欧美综合婷婷欧美综| 丁香五月婷婷乱| 欧美黄色AA片哗啦啦啦| 播五月开心婷婷欧美综合| 激情综合无码| 久久99久久99精品免视看婷婷| 午夜69成人做爰视频| 亚洲午夜国产成人电影VA国产欧…| 久久婷婷桃花五月天| 91超级碰在线| 亚洲色婷婷| 五月丁香婷婷激情| 婷婷99狠狠躁| 婷婷五月丁香久久| WWW.桔色成人.COM| 超碰A V在线| 天天射美女| 人妻久久久久久久久妻久久久久| 九九免费精品| 97人人操在线| 成人无码精品1区2区3区免费看| 婷婷六月香| 91vip在线观看| 丁香五月激情六月综合| 96丁香六月婷婷蜜桃综合久久| 夜夜操夜夜操| 成人AV播放| 啊v视频在线观看| 内射激情在线| 97丁香五月| 无码少妇高潮喷水A片免费| 欧美啪啪网| 99热网站在线观看| 免费视频99| 五月丁香婷婷色| 丁香五月WWW| 激情五月综合视频| 婷婷五月天高清无码| 99精品在这里| 日韩啪啪自拍| 在线视频色五月| 99精品视频免费| av九九| 玖玖婷婷视频| 久久视频婷婷视频| 99热亚洲精品| 色色色色色色综合网| 91无码视频| www.激情五月天| 丁香五月天综合| 毛片蕉地一二| 伊人国产婷婷五月天| 99人碰碰碰| 另类图片五月激情| 色五月婷婷成人视频| 天天综合五月| 五月天婷婷激情六月久久 | 婷婷色色综合激情| 991精品在线视频| 国产首页在线| 99在线免费视| 97在线碰| 婷婷激情五月天小说| 6080av| 99无码精品| 色域五月婷婷丁香| 深爱激清网| 99色爱| 亚洲国产精品五月天| 99热亚洲| 成人人操| 色噜噜婷婷| 亚洲日韩一页精品发布| 婷婷丁香五月天哟啪| 综合色影| 六月丁香婷婷综合影院| 婷婷丁香人妻久久在线观看| 亚洲综合在线视频| 激情四射五月天| 天天综合色丁香| 超级碰碰视频无码| 久久久久久综合五月婷婷| 99只有精品| 青青草原中文字幕| 四虎成人精品永久免费AV九九| 亚州激情九月| 丁香婷婷激情网站| www五月婷婷| 69婷婷丁香午夜| 国产乱妇无乱码大黄AA片| 永久思思热在线| 美女五月天| 五月婷婷基地| 伊人久久婷婷| 激情久久五月天| 婷婷欧美综合| 亚洲婷婷91丁香| 99热新网址| 国产97色在线| 五月丁香成人| 色情久久久| 五月婷婷六月丁香综合| 九月激情综合| www.久久久久久久| 一区视频网站| 免费黄色片子| 99精品在线观看| 99精品无码| 妻久久久久| 色五月激情五月| 久8色色| 五月婷婷色色网址| 免费AV在线|