在調試中學習 Rust

Rustlings 是 Rust 團隊推出的一個開源項目,旨在幫助初學者在調試程序過程中學習 Rust 語言。

學習一門計算機語言除了比較直白的方法是閱讀別人優秀的代碼和親自上手編寫大量的代碼,還有就是實踐中得真知。這篇文章的本意是側重於實踐,並介紹通過調試代碼來學習。

具體點,準備一些現成的工程代碼(也可以是你自己的代碼),但這些代碼或多或少存在一些錯誤,需要同學們自己在編譯過程閱讀編譯器輸出的錯誤信息和修復建議,並手動修復工程代碼中蘊含的錯誤,然後再次編譯,如此重複,直到工程能夠完整編譯結束和順利運行。

恰好,Rust 團隊提供了一個開源項目 Rustlings,就是爲了契合這種學習思路,以幫助各位初學者順利入門 Rust 語言。

下面開始我們的初體驗吧!

安裝 Rustlings

由於 Rustlings 依賴於 rust 工具鏈的應用,所以在安裝 Rustlings 之前,你需要確保你所用的系統已經準備好 rust 的工具鏈環境。如果還沒有,可以參考我的文章《簡明快速配置 Rust 工具鏈》

官方推薦的安裝方式是通過下載它的安裝腳本,然後在本地執行該腳本,該腳本會自動下載所有依賴包並編譯安裝,最終會安裝好最新版 Rustlings。

下載安裝腳本

如果上面在執行 curl 下載腳本文件時老是提示連接失敗,估計是被牆了,可以在公衆號回覆關鍵詞【rustlings_install】獲取我的網盤備份。

運行安裝腳本

安裝腳本會克隆 rusdlings Git 存儲庫,並安裝運行示例程序所需的所有依賴項。

好了,現在 rustlings 已經在你的環境裏安裝完畢。

動起手來

一切從 rustlings 指令開始,輸入指令 rustlings 看看

顯示末尾有個提示信息,意思是說 rustlings 指令應該在 rustlings 目錄下執行

不要驚慌!Rustlings 就是面向初學者的,它將通過一系列的調試實踐,來教會你如何使用 rust 編寫代碼。

  1. Rustlings 的核心理念就是讓使用者從實踐中掌握學習內容,而不是停留在死記硬背語法和教條主義中。所謂的實踐就是,提供一系列帶有錯誤的練習代碼片段,每個練習對應一個樣例程序,問題可能是語法層面的,也可能是邏輯方面的,要求使用者從中發現問題並修正代碼,以到達正常編譯和測試運行。

  2. 官方推薦直接使用 watch 模式,在 watch 模式下,系統會自動開始第一個練習。所以,不要對彈出的錯誤信息感到驚慌,它只是提醒你 --- 調試練習開始了。

  3. 假如在解決問題的過程中,發現需要幫助的時候,系統可以提供幫助信息。如果你正在 watch 模式下,請輸入 hint 獲得幫助信息,否則請直接執行 rustlings hint exercise_name 命令,exercise_name 就是當前你需要獲取幫助信息的練習名。

  4. 當然,你如果發現有些問題不適合被公示出來討論,那麼你可以向 rustlings 的 github 倉庫提交內容,鏈接如下 https://github.com/rust-lang/rustlings/issues/new

  5. 在 rustlings 裏同樣可以使用代碼補全功能,輸入 rustlings lsp 命令即可。

列出所有練習

在 rustlings 安裝目錄下有個專門目錄,用於存放練習示例程序

同時 rustlings 也提供了命令直接顯示所有的練習、各個練習的安裝路徑和狀態

各個練習默認狀態爲待確認(Pending)狀態。

在 rustlings list 命令返回的所有信息結尾處,有一份簡短的練習進度報告,這樣你可以據此跟蹤自己的學習進度。

聰明的你已經想到了,你可以用這條命令來幫你回憶上次練習到哪一步了。

上面這份報告顯示我還是比較懶的,全部 96 個練習完全沒動靜,So ....

查看練習代碼

既然已經知道練習的程序存放在哪裏,那麼就可以隨時通過完整路徑查看這些練習程序的代碼。

一般我習慣用 vscode 編輯和閱讀代碼,所以我推薦先導航到代碼目錄,然後用 vscode 打開當前目錄。如果你是在 Windows 環境下,可以鼠標右鍵直接打開,或者 Linux 環境下,可以在終端裏輸入以下命令

$ code ./

開始調試

rustlings 提供了推薦的練習順序,第一步可以輸入 rustlings verify,自動開始按照推薦的順序驗證下一個待確認的練習程序,包括先編譯然後運行,同時輸出結果。

開始的時候,可以不做任何修改,直接執行自動驗證

看到上面的輸出之後,你會發現系統推薦的練習順序其實就是 rustlings list 輸出的順序,而這裏由於所有練習都是待確認狀態,所以從第一個開始,就是 exercises/intro/intro1.rs,編譯和運行過程沒有報告任何錯誤。

但是你還是可以動手嘗試修改,看看輸出會怎樣變化,然後再次運行 rustlings verify,雖然輸出結果都是正確的,但還是停留在第一個練習的例子。

那麼如何開始下一個練習並結束當前的練習呢?

進行下一個練習

Rustlings 系統會在開始驗證之前,先遍歷檢索所有的練習程序源代碼中的這行註釋內容

// I AM NOT DONE

如果某個練習程序源代碼中的這行註釋內容是存在的,則認爲該練習程序未完成,即使該練習程序代碼能成功編譯通過並運行。所以,在你確認完成某個練習後,務必刪除 I AM NOT DONE,再繼續下一個練習,這樣執行指令 rustlings verify 纔會開始下一個練習。

刪除 I AM NOT DONE 後,再次執行 rustlings verify 就直接開始了下一個練習。

從上面的輸出來看,intro2.rs 編譯過程出了問題,應該是語法層面的問題。這個報錯信息還是很到位的,它的意思是 println! 的格式字符串裏用了 1 個佔位符 {} ,但是後邊沒有提供參數,需要補充參數,可以直接動手修復源碼的問題。

如果這些練習的代碼中碰到比較棘手的問題,而且編譯器報錯信息沒有直指弊端呢?有沒有更具體的修改建議?往下看!

獲取提示

Rustlings 提供了 hint 命令可以獲取更加準確的問題描述和修復建議。

$ rustlings hint intro2
Add an argument after the format string.

可以看到這樣的提示信息明顯更有針對性,但這個提示命令 hint 僅能應用於 rustlings 提供的練習源代碼上。

嘗試修復一下 intro2 的問題

fn main() {
    println!("Hello {}!""world");
}

再次運行驗證

指定練習

突然間,你可能發現有些練習就是想提前練練手,那麼可以使用 rustlings run 命令跳過推薦順序,然後專門對某個練習程序執行驗證。

這裏嘗試對 exercises/tests/tests1.rs 執行驗證

tests1 源碼的目標是對函數 you_can_assert 執行測試,但是編譯器報錯提示函數 you_can_assert 在調用宏 assert! 時沒有提供參數,修復建議是在宏 assert! 後邊添加布爾表達式作爲參數,這裏填充簡單的真值 true 試試。

#[cfg(test)]
mod tests {
    #[test]
    fn you_can_assert() {
        assert!(true);
    }
}

再次執行 rustlings run tests1,沒有任何的輸出,表示測試程序沒有捕捉到任何異常,測試正常結束,驗證也通過。

如果在宏 assert! 後邊添加假值 false 呢?

從上面的輸出來看,測試程序捕捉到了異常,並結束測試流程,然後輸出測試結果彙總。

快捷方式

每次啓動練習都需要輸入練習程序名稱實在是太囉嗦了,rustlings 爲你提供了一個快捷的 next 命令,使用它可以按照系統推薦順序直接開始下一個練習

$ rustlings run next

自動檢測改動

還記得上面提過 watch 模式吧?這個 watch 模式有什麼妙用嗎?

它就是用來監測練習對應的源代碼是否有改動,如果有改動就立刻執行驗證,相當於自動執行了 rustlings verify。起碼,不用每次需要重新驗證時,都要手動敲一次命令了,真的是妙。

怎麼進入 watch 模式?

$ rustlings watch

更多

Rustlings 也提供了幫助命令,查看有哪些選項可用,和詳細介紹

$ rustlings --help

認知從實踐中來

從上面看來,Rust 編譯器在處理源碼後,會輸出非常有意義的錯誤提示,這對開發者理解代碼中的語法錯誤頗有裨益,而且會提高調試效率。

對於初學者來說,沒有最好,只有更好。所以,有好事者就開發了 Rustlings 這個項目,在系統中專門利用調試過程以及一系列的工具幫助 Rust 初學者練習調試。

Rustlings 是練習 Rust 調試、理解 Rust 語法的一個非常好用的系統。希望上面的內容對你有幫助!

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/EFd0bEZmfxySjmSWrOcS5g