五月天青色头像情侣网名,国产亚洲av片在线观看18女人,黑人巨茎大战俄罗斯美女,扒下她的小内裤打屁股

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

超干貨!大型 Rust 項目經(jīng)驗分享| Databend 與您共同進步

2021-12-10 11:50 作者:Databend  | 我要投稿

原文:[https://matklad.github.io/2021/08/22/large-rust-workspaces.html](https://matklad.github.io/2021/08/22/large-rust-workspaces.html)

譯者:韓玄亮(一個熱愛開源,喜歡 rust 的 go 開發(fā)者)


在本篇文章中,我將分享我組織大型Rust項目的經(jīng)驗。但這絕不是權(quán)威的,只是我通過嘗試和錯誤中發(fā)現(xiàn)的一些小技巧。

Cargo,作為Rust的構(gòu)建系統(tǒng),遵循約定大于配置的原則。它不僅為小型項目提供了一套良好的默認(rèn)配置集,尤其為公共 crates.io 庫量身定做。雖然這些默認(rèn)值并不完美,但它們已經(jīng)足夠用了。這對整個生態(tài)系統(tǒng)的一致性也是值得歡迎的。

然而當(dāng)涉及到大型的、多crate的項目時,Cargo就不那么統(tǒng)一了,它被組織成一個Cargo工作空間。而工作空間是靈活的 —— Cargo對工作空間的布局并沒有一個偏好統(tǒng)一。因此,人們會嘗試不同的東西,取得不同程度的效果。

回到標(biāo)題,我認(rèn)為對于代碼行數(shù)在一萬到一百萬之間的項目,扁平化結(jié)構(gòu)是最為合理的。此處 [rust-analyzer](https://github.com/rust-analyzer/rust-analyzer) (多達200k行)是一個比較好的例子,它的項目組織如下:


在 repo 的根部,Cargo.toml 定義了一個虛擬清單:

其他的東西(包括 rust-analyzer "main" crate)都嵌套在 `crates/` 下的某一個層級中。每個目錄的名稱都等于 `crate` 的名稱。


在撰寫本文時,`crates/` 中有32個不同子文件夾。

扁平式比嵌套式更好

有趣的是,這個建議和按層級組織的習(xí)慣傾向(注:按照我們平時開發(fā)習(xí)慣來說)剛好對立:


在這種情況下,有幾個原因可以說明樹形結(jié)構(gòu)是低級的:

1. crates的cargo分級命名空間是扁平的。在 `Cargo.toml` 中不可能寫出 `hir::def` ,所以一般crate的名字中都有前綴。樹狀排列創(chuàng)造了另一種層次結(jié)構(gòu),這就增加了不一致的可能性。

2. 即使是比較大的列表也比小的樹更容易讓人一目了然。`ls ./crates` 給出了項目的層級概覽,而且這看起來足夠小。


在基于樹狀結(jié)構(gòu)的布局做同樣的事情比較困難的:

- 只從單層級上看并不能告訴你哪些文件夾包含嵌套的 crate

- 而在所有層級上看又會列出太多的文件夾(無關(guān)文件干擾視覺)

**正確方式**:***只看包含Cargo.toml的文件夾可以得到正確的結(jié)果,但并沒有 `ls` 那樣簡單***。

嵌套結(jié)構(gòu)確實比扁平結(jié)構(gòu)更容易擴展。但常數(shù)很重要 —— 在你達到一百萬行代碼之前,項目中的crates數(shù)量可能會充滿一個屏幕。

3. 層級布局的最后一個問題是:***沒有完美的分層結(jié)構(gòu)***。但是對于扁平結(jié)構(gòu),增加或拆分crates的代價微不足道。在樹狀結(jié)構(gòu)下,你需要弄清楚把新的crate放在哪里,而且,如果已經(jīng)沒有一個完美的匹配,你將不得不選擇以下幾種情況:

- 在頂部附近添加一個愚蠢的空的文件夾

- 添加到一個巨無霸的utils文件夾

- 將代碼放在一個已存在但是不是很理想的目錄中(*所以結(jié)構(gòu)會隨著維護而慢慢惡化*)

對于長期維護的多人項目來說,這是一個重要的問題 —— 樹狀結(jié)構(gòu)往往會隨著時間的推移而惡化,而扁平結(jié)構(gòu)則不怎么需要維護。

小技巧

讓工作空間的根部成為虛擬清單。

這可以驅(qū)使我們把main crate放在根目錄下,但這樣做會使根目錄被 `src/` 污染,需要在每個 Cargo 命令中傳遞 `--workspace`,并向其他一致的結(jié)構(gòu)添加異常。

?**反對從文件夾名稱中去除普通前綴。**

如果每個板塊的名字都和它所在的文件夾一模一樣,這讓導(dǎo)航和重命名就會變得更容易。反向依賴的Cargo.toml同時提到了文件夾和crate的名稱,當(dāng)它們完全相同的時候就很有用。

**對于大型項目來說,很多版本庫的臃腫往往來自于自動化。**

Makefiles和各種prepare.sh腳本。為了避免臃腫和臨時工作流程的泛濫,可以將所有的Rust自動化寫在一個專門的crate里。這里安利一個有用的庫:[cargo-xtask](https://github.com/matklad/cargo-xtask)。

?**對于你不打算發(fā)布的內(nèi)部crate,可以使用 `version = "0.0.0"`。**

如果你確實想發(fā)布具有符合語義版本API的crate的子集,那么要非常慎重對待它們。將所有這樣的crate提取到一個單獨的頂層文件夾,即 `libs/`,這樣做對未來可能是有意義的。這使得檢查 `libs/` 中的東西是否使用了 `crates/` 中的東西更加容易。

**由一個文件組成一個 crate。**

對于這些文件,我們很容易陷入:把 `src` 目錄展開,把 lib.rs 和 Cargo.toml 放在同一個目錄下。但是我建議不要這樣做 —— 即使crate現(xiàn)在是單文件,以后也可能會被擴展。


超干貨!大型 Rust 項目經(jīng)驗分享| Databend 與您共同進步的評論 (共 條)

分享到微博請遵守國家法律
宁乡县| 忻州市| 化隆| 平顶山市| 雷山县| 辽中县| 乌鲁木齐县| 昌平区| 栾川县| 澄迈县| 揭阳市| 阳新县| 合肥市| 库尔勒市| 云霄县| 怀宁县| 千阳县| 松江区| 龙川县| 南丰县| 孝感市| 远安县| 沁源县| 翁源县| 罗城| 北辰区| 兴城市| 清新县| 洪湖市| 安岳县| 昌图县| 铁岭县| 崇左市| 桐庐县| 黄大仙区| 军事| 毕节市| 海晏县| 高唐县| 和平区| 财经|