具代表性的面試主題

程式設計面試:Rust 1.96 新 Range 型別與 assert_matches 如何遷移?

程式題中等
Offer.cc 編輯團隊發佈 更新

題幹

一個 Rust 函式庫需要保存可複製的切片範圍,並希望測試失敗時顯示實際值。你會如何採用 Rust 1.96 的新 Range 型別與 assert_matches,同時避免舊範圍語義與版本相容問題?

題幹與適用場景

你維護一個解析函式庫:索引範圍會被多個輕量控制代碼複製,測試需要在模式不符合時輸出值。專案目前使用舊的 core::ops 範圍與 matches!,準備升級到 Rust 1.96。請說明新範圍型別、迭代語義、公開 API、斷言巨集與發布策略。

面試官考察點

  • 是否理解舊 Range 實作 Iterator,新 core::range 型別改為 IntoIterator 並可 Copy
  • 是否能避免把語法 0..n 誤認為已自動切換到新型別。
  • 是否知道 assert_matches! 不在 prelude,需要明確匯入並適合診斷失敗值。
  • 是否處理 MSRV、文件、巨集展開、Wasm 連結變化與回滾。

回答前需要釐清的問題

  1. 函式庫的 MSRV 是 Rust 1.96,還是必須繼續支援舊編譯器?
  2. 範圍需要保存後再迭代,還是只在一次迴圈中消費?
  3. 對外 API 接受任意 RangeBounds,還是暴露具體範圍型別?
  4. Wasm 建置是否依賴未定義匯入,升級 1.96 後是否需要明確連結參數?

30 秒回答框架

我會把可複製的區間控制代碼改為 core::range 型別,並讓遍歷發生在明確的 IntoIterator 轉換中;通用 API 優先接受 RangeBounds,避免鎖定具體實作。測試中明確匯入 core::assert_matches,保留模式判斷並列印實際值。遷移前固定 MSRV、檢查 0..n 仍產生舊型別的事實,補充型別與行為測試,並另外驗證 Rust 1.96 對 Wasm 未定義符號的連結收緊。

分步驟深入解答

1. 區分兩套範圍語義

Rust 1.96 穩定了 core::range::RangeRangeFromRangeInclusive 及其關聯迭代器。新型別實作 IntoIterator,因此能放進 Copy 結構;現有範圍語法暫時仍產生舊型別,未來版本才會在 edition 中切換。程式碼審查必須看型別簽名,不能只看 0..n 外觀。

2. 設計函式庫 API 與生命週期

若 API 只讀取邊界,接受 RangeBounds 可同時相容舊、新範圍;若需要保存範圍並複製,使用新型別並在邊界處轉成迭代器。切片索引仍應驗證起止位置與字元邊界,不能因型別可 Copy 就跳過越界檢查。公開文件標註 MSRV,避免下游在舊工具鏈上意外失敗。

3. 使用模式斷言改善診斷

assert_matches!debug_assert_matches! 等價於帶模式的斷言,但失敗時展示被匹配值。它們不在 prelude,測試模組明確匯入即可;生產程式碼不要用 debug_assert_matches! 承擔安全驗證,因為 release 建置會移除 debug 斷言。對錯誤列舉的關鍵欄位使用窄模式,避免輸出敏感載荷。

4. 評估升級風險

Rust 1.96 同時收緊 Wasm 目標的未定義符號連結:預設不再傳遞 --allow-undefined。若專案有意依賴匯入,必須明確連結參數或標註匯入模組,並在 CI 中建置 Wasm。升級分支應執行舊版相容矩陣、文件範例、測試與二進位產物檢查,失敗時可回退編譯器與依賴鎖檔。

高品質示範回答

我會先把 MSRV 與支援的目標平台寫進發布契約。保存型控制代碼使用 Rust 1.96 的 core::range::Range,因為它可複製且透過 IntoIterator 遍歷;通用函式則接受 RangeBounds,避免把呼叫方綁定到某個具體型別。程式碼中不假設 0..n 已經是新型別,而是透過型別檢查與行為測試確認。測試模組明確匯入 core::assert_matches,用窄模式輸出失敗值,同時保留普通 matches! 作為輕量布林判斷。升級還要驗證 Wasm 未定義符號:預設連結會失敗時,只有確實需要匯入的模組才明確設定 --allow-undefined 與匯入模組標記。CI 執行 MSRV、最新穩定版、Wasm 建置與文件範例,任何失敗都阻止發布。

常見錯誤

  • 認為 0..n 在 Rust 1.96 已自動產生 core::range 新型別。
  • 把新範圍當作 Iterator 直接呼叫,忽略其 IntoIterator 設計。
  • 依賴 prelude 中不存在的 assert_matches! 匯入。
  • 用 debug 斷言承擔生產安全檢查。
  • 因為範圍可 Copy 就省略邊界、溢位或字元邊界驗證。
  • 升級後忽略 Wasm 未定義符號連結行為變化。

追問及應對

為什麼不把所有 API 都改成新 Range?

具體型別會擴大 MSRV 與相容壓力。接受 RangeBounds 能相容呼叫方,只有需要保存並複製的內部結構才值得使用新型別。

assert_matches!matches! 何時分別使用?

只需要布林結果時用 matches!;測試失敗需要看到實際值和模式時用 assert_matches!。不要讓斷言巨集取代業務錯誤處理或安全驗證。

Wasm 匯入必須保留怎麼辦?

先確認匯入是設計契約而非連結設定遺漏,再透過明確 --allow-undefinedwasm_import_module 標註恢復行為,並把符號清單與執行時驗證加入 CI。

公開來源

同類題目

相關面試工具

用 Screenshot 處理演算法題

截圖題目後,依序看約束、解法、程式碼、邊界條件和複雜度。

查看工具