Rust 中"上下文"設計構想 - Tyler Mandry

banq發表於2021-12-22

我最近與Niko MatsakisYoshua Wuyts想出了一個很有前途的想法來解決我稱之為 Rust 中的“上下文問題”。這個想法的靈感來自其他語言的特性,比如隱式引數、效果和物件功能。雖然這還處於開發的早期階段,但我在這裡分享它是希望從 Rust 社群獲得更多的觀點和想法。
 

問題
在程式設計中,我們經常發現自己需要在程式碼的許多地方訪問某個上下文物件。上下文物件的一些示例:

  • 競技場分配器
  • 字串內部
  • 記錄範圍
  • 非同步執行器
  • 能力物件

今天我們有兩種主要的方法來使用這些上下文物件。
一種是將上下文作為引數新增到每個傳遞依賴於它的函式中。這很不方便(儘管有時可以透過將其儲存在結構中並透過self引數走私來使其更容易)。比不便更糟糕的是,如果您需要透過您無法控制的程式碼來執行緒化上下文,您就會陷入困境——除非該程式碼的作者提供了一種通用的方式來傳遞上下文。
傳遞上下文的第二種方式是使用一種全域性變數,通常是執行緒區域性變數。
thread_local!(static RUNTIME: Option<async_std::Executor> = None);
這使得傳遞上下文變得更加容易,包括透過您無法控制的程式碼。對於許多用例,這是一個很好的解決方案。但是執行緒區域性變數存在很多問題:
  • 不支援堆疊分配
  • 他們需要平臺支援
  • 解構函式通常不會執行
  • 它們通常不適合圖書館使用
  • 它們不會被在其他執行緒上執行的邏輯巢狀程式碼繼承,例如 rayon scope任務
  • 他們需要內部可變性
  • 它們需要靜態初始化,這實際上意味著將上下文儲存在 Option 中並展開,或使用類似的東西 lazy_static!
  • 它們不符合人體工程學:每次使用都需要引入一個封閉裝置;沒有通用的“範圍設定器”

 

宣告你的上下文
如果 Rust 程式碼可以改為宣告它需要的上下文,並且編譯器負責確保提供了該上下文會怎樣?
這個一般概念在其他語言中由幾種不同的方法解決:

  • 依賴注入
  • 隱式引數
  • 效果Effects

這裡提出的方法像隱式引數一樣工作,與其他語言的效果在句法和概念上有一些相似之處,這使得它更方便並更好地整合到 Rust 的型別系統中。它還可以用於實現依賴注入。這種方法:
  • 執行時開銷為零;它編譯成你無論如何都會寫的程式碼
  • 靜態保證您需要的任何上下文都可用
  • 允許傳遞對堆疊上物件的引用
  • 與特質系統整合
  • 遵循簡單的規則

。。。。
原文點選標題
 

結論
在這篇文章中,我們看到了一種在 Rust 中共享上下文的新方法。它允許在不汙染呼叫站點的情況下傳遞上下文,甚至可以透過您無法控制的程式碼。它可以在應用程式程式碼和庫程式碼中使用。它需要對型別系統進行高階擴充套件,但要使用已經熟悉的概念(如生命週期),作為回報,我們可以使用 Rust 語言對重要模式(如功能)進行建模。
 

相關文章