受不了 Rust 這些問題,我將后端切換到了 Go_熱文

發(fā)布時間:2023-01-08 12:33:02  |  來源:騰訊網(wǎng)  

作者 | Anthony Oleinik

譯者 | 平川


(相關(guān)資料圖)

策劃 | 劉燕

本文最初發(fā)布于 Level Up Coding 博客。

別激動!我能感受到你點擊這篇文章時懷有的憤怒。我并不討厭 Rust——在許多場景中,我都傾向于使用它。所有編程語言都是達成目的的手段。然而,就我要處理的場景而言,Rust 并不是很適合,我不得不把這個項目推倒重來,用 Golang 重寫。

該項目是 Hasura 的一個簡單的后端 webhook 服務(wù)。你可能不了解 Hasura,那是一個 Postgres 數(shù)據(jù)庫封裝器,可以即時提供 GraphQL API。對于像我這樣獨自開發(fā)個人興趣項目的人來說,這非常方便:每個 REST 端點或 GQL 解析器都要編寫的話會耗費大量的時間,而且每個模型的 CRUD 操作基本相同。當(dāng)需要一些比較復(fù)雜的邏輯時,它就不那么有效了——為此,Hasura 允許你將 GQL 請求映射到自定義 webhook。舉例來說,我就是用這種方法進行 S3 文件上傳或身份驗證。

問題 1:依賴注入難

Rust 依賴注入是一個有趣的問題。如果你需要一個具體的類型,如:

你必須給 do_stuff 傳遞一個 Database 實例;概莫能外!你不能“子類化”Database (Rust 沒有子類的概念)。所以,如果你是一個不自己測試代碼的程序員,那么這完全沒問題;實際上,你只會有一個 Database 的實現(xiàn),因此也就沒有理由讓這個函數(shù)接受 Database 以外的任何東西。

那我們測試人員呢?我們必須重寫函數(shù)簽名。Database 需要是 trait 類型的,然后我們把那個它在 mock 對象上實現(xiàn)。好吧,還不算太壞。事實上,在 Golang 中,我做的事情基本相同;那到底是從哪里開始有問題的呢?

問題 2:異步 Trait

在 Rust 中,異步很簡單,trait 也很簡單,但異步 trait 卻有些困難。我在 Rust 中找到的大多數(shù)異步 trait 示例都用了 async_trait 宏。這很有幫助,我正在用它,體驗還不錯。

以下是我到目前為止對這個過程的一個總結(jié):

編寫一個結(jié)構(gòu);開心。

編寫一個測試;意識到無法依賴注入。難過。

將結(jié)構(gòu)轉(zhuǎn)換為 trait;開心。

心滿意足地依賴注入。

使用 mockall crate 自動生成 mock。非常非常開心!

做一個異步 http 調(diào)用。

需要用一個特殊的宏實現(xiàn)異步 trait。

意識到這個宏無法很好地與 Mockall 一起工作。

難過。

事后來看,這個問題是有辦法解決的。也許在切換到 Go 之前我應(yīng)該再試一次,但那時,下面這一點已經(jīng)讓我有點沮喪了……

問題 3:編譯慢(致命一擊)

Rust 的編譯時間很糟糕。我們已經(jīng)聽過無數(shù)次了;不可能有一種無所不能卻沒有缺點的語言。那是不可能的——Rust 的缺點是難以理解的生命周期以及糟糕的編譯時間。

我有一臺漂亮耐用的筆記本電腦 M1 Mac,那可是一頭老黃牛。在我的 Mac 上編譯 Rust 絕對沒有問題。通常,在編寫服務(wù)器時,我會在本地開發(fā),并且要保證每次有修改時,本地服務(wù)器會重新加載,讓我可以在提交真正的單元測試之前非??焖俚販y試功能。兩次試驗之間需要進行大量的編譯;可以接受!還是說,在 Mac 上編譯 Rust 沒有問題。

在容器里嗎?還是算了吧。

對我來說,要編排許多本地服務(wù)而又不用費事在每個服務(wù)(Hasura、Web 鉤子、mock s3、mock oauth 服務(wù)器……)中運行 npm run ,最簡單的方法是有一個 docker-compose.yaml 文件可以運行所有這些東西。通常就是一個 docker-composition.dev.yaml 文件,因為我實際上并不使用 docker compose 進行部署。只在本地進行開發(fā)。然而,這有一個副作用,就是我的 Rust 代碼需要在容器中編譯,因為:必

須自動熱重載。

必須在容器里開發(fā)。

我有兩個選擇:要么啟動一個可能會跑死整臺計算的巨大鏡像,以便在其中編譯 Rust 代碼,要么就要與 3 分多鐘的編譯時間周旋。開發(fā)周期陷入停滯,讓我感覺非常低效。我試著改變工作流程,在手動測試之前編寫代碼和測試,或者不使用自動熱加載,但糟糕的是,我就是沒能做到。

最后,我咬緊牙關(guān),換成了 Go。讓人懷念的 Rust:我非常喜歡編寫 Rust 代碼。我覺得它漂亮而富有表現(xiàn)力,實用而優(yōu)雅。

如果我正在編寫本地輔助庫、性能敏感代碼、任何不需要在容器中運行的后端服務(wù)……那么,Rust 會是我的第一選擇。特別是如果我不需要說服其他任何人使用它。

對于我提到的問題,特別是最后一個問題,如果你有任何解決方法,請務(wù)必告訴我。我想讓 Rust 回到項目中,我愿意回到舊版本,并將其提升到同等水平。

https://levelup.gitconnected.com/why-i-switched-from-rust-to-go-on-the-backend-28bda21dbee9

聲明:本文為 InfoQ 翻譯,未經(jīng)許可禁止轉(zhuǎn)載。

關(guān)鍵詞: Rust 這些問題 我將后端切換到了 rust infoq docker

 

網(wǎng)站介紹  |  版權(quán)說明  |  聯(lián)系我們  |  網(wǎng)站地圖 

星際派備案號:京ICP備2022016840號-16 營業(yè)執(zhí)照公示信息版權(quán)所有 郵箱聯(lián)系:920 891 263@qq.com