AlexZhang

AlexZhang

用 ChatGPT 打造最強 Rust 輔助學習“魔法”系統

WechatIMG466

建議朋友們先學習 《Prompt 指南》 之後閱讀本文更好。建議使用 GPT-4,如果沒有 GPT-4 ,用 3.5 也可以打造這個系統,只不過 GPT-4 更加精準一些。另外,這套系統你也可以應用到其他編程語言上面。 題圖為本人使用 Midjourney 所畫的《阿姆斯特丹港口的咖啡館》。

引子#

最近在跟風玩 AI ,包括 ChatGPT 和 Midjourney,體驗一下傳說中年薪百萬美元的 Prompt 工程師是什麼感覺。直到這周,我發現 GPT4 對於 Rust 代碼的輔助學習非常有幫助。於是,我就嘗試打造這個 Rust 輔助學習系統,我將其命名為 RustChat ,在 GitHub 上創建了倉庫,方便大家交流。

在我們學習 Rust 的時候,如果手頭有一個稱手的系統,可以隨時出題來考察我們的知識點,並且能給出準確的答案和解釋。或者,在我們不知道該做什麼項目練手的時候,能給我們推薦項目 idea ,該多好。

現在有了 AI ,我們就可以打造這樣一個神奇且有用的系統了。

RustChat : 最強 Rust 輔助學習 “魔法” 系統介紹#

先來講一下思路。既然想要指令 prompt 模式,那麼就應該像設計程序 API 一樣,先把指令格式設計出來。

值得說明的是,這個思路看似比較簡單,但是在大量嘗試以後摸索出來的。之前失敗的設計帶來的結果就是某個新增的指令直接打破了 GPT 的舊設定,導致指令混亂。

“魔法” 設計#

以下列出我想要實現的指令 prompt 示例:

work               // work 為主指令,代表輸出工作級的 Rust 題目
work -tech trait   // `-tech` 表示一级指令,代表要輸出對指定內容 trait 的工作級概念講解,並且附帶代碼示例
work -tech --cn trait // `--cn` 表示二級指令,代表將主指令和一级指令設定的輸出內容以指定的語言中文來輸出
work -type --en eBPF  // `-type` 表示一级指令,代表要輸出指定內容 eBPF 的工作級題目,
work -idea --cn   // `-idea` 表示一级指令,代表要輸出對應主指令級別的項目實踐想法和思路供人參考,  `--cn` 表示二級指令,代表以指定的語言中文來輸出內容

題目我打算分為三個級別:

  1. 工作級別。工作級別問題是覆蓋 入門以及日常編寫 rust 代碼的常用特性和知識。
  2. 專業級別。專業級別覆蓋 Rust 專家級特性和知識點。
  3. Quiz 類型。 Quiz 類專門考察容易令人困惑的 Rust 語言特性的題。

主指令對應這三個級別分別為:

  1. work 指令,對應 工作級別的題目。
  2. expert 指令,對應專業級別題目。
  3. quiz 指令,對應 Quiz 級別題目。
  4. anwser 指令,用來指定應該回答的問題數。

接下來介紹一级指令,一级指令是可以和主指令進行任意組合:

  1. -tech ,表示一级指令,代表要對其後指定的內容輸出相應主指令級別的概念講解,並附帶示例。
  2. -type ,表示一级指令,代表要對其後指定的內容輸出相應主指令級別的題目。
  3. -idea,表示一级指令,代表要輸出對應主指令級別的項目實踐想法和思路供人參考。
  4. -crate,表示一级指令,只限主指令 work 使用,代表要對其後指定的內容推薦相應的第三方 crate
  5. -n ,表示一级指令,只限主指令 anwser 使用, 代表要回答的問題數目。

接下來介紹二級指令,二級指令可作用於一级指令後面:

  1. --cn,表示二級指令,代表以中文來輸出內容
  2. --en,表示二級指令,代表以英文來輸出內容
  3. --jp,表示二級指令,代表以日文來輸出內容

那麼這個輔助學習系統應該支持的指令如下:

work               // work 為主指令,代表輸出工作級的 Rust 題目
work -tech trait   // `-tech` 表示一级指令,代表要輸出對指定內容 trait 的工作級概念講解,並且附帶代碼示例
work -tech --cn trait // `--cn` 表示二級指令,代表將主指令和一级指令設定的輸出內容以指定的語言中文來輸出
work -type --en eBPF  // `-type` 表示一级指令,代表要輸出指定內容 eBPF 的工作級題目,
work -crate eBPF   // `-crate` 表示一级指令,代表要推薦指定內容 eBPF 的第三方 crate
work -idea --cn   // `-idea` 表示一级指令,代表要輸出對應主指令級別的項目實踐想法和思路供人參考,  `--cn` 表示二級指令,代表以指定的語言中文來輸出內容
anwser -n 2 ,// 表示一级指令,只限主指令 `anwser` 使用, 代表要回答當前這條指令前的兩個問題
expert               // work 為主指令,代表輸出工作級的 Rust 題目
expert -tech trait   // `-tech` 表示一级指令,代表要輸出對指定內容 trait 的工作級概念講解,並且附帶代碼示例
expert -tech --cn trait // `--cn` 表示二級指令,代表將主指令和一级指令設定的輸出內容以指定的語言中文來輸出
expert -type --en eBPF  // `-type` 表示一级指令,代表要輸出指定內容 eBPF 的工作級題目,
expert -idea --cn   // `-idea` 表示一级指令,代表要輸出對應主指令級別的項目實踐想法和思路供人參考,  `--cn` 表示二級指令,代表以指定的語言中文來輸出內容
quiz               // work 為主指令,代表輸出工作級的 Rust 題目
quiz -tech trait   // `-tech` 表示一级指令,代表要輸出對指定內容 trait 的工作級概念講解,並且附帶代碼示例
quiz -tech --cn trait // `--cn` 表示二級指令,代表將主指令和一级指令設定的輸出內容以指定的語言中文來輸出
quiz -type --en eBPF  // `-type` 表示一级指令,代表要輸出指定內容 eBPF 的工作級題目,
quiz -idea --cn   // `-idea` 表示一级指令,代表要輸出對應主指令級別的項目實踐想法和思路供人參考,  `--cn` 表示二級指令,代表以指定的語言中文來輸出內容

打造 prompt#

接下來我們就來打造 prompt。 為了確保 GPT-4 可以完整地理解設計的 “魔法”,應該採取「整體到細節」的步驟逐步來 “喂” 它。

一、設定主指令

請你化身為 Rust 專家,來按我的要求幫我生成 Rust 題目,題目默認包括一道選擇題和一道編寫代碼實現的題。默認以中文輸出,除非指定了相應的二級指令來告訴你題目數量。

題目我打算分為三個級別:

1. 工作級別。工作級別問題是覆蓋 入門以及日常編寫 rust 代碼的常用特性和知識。
2. 專業級別。專業級別覆蓋 Rust 專家級特性和知識點。
3. Quiz 類型。 Quiz 類專門考察容易令人迷惑的 Rust 語言特性的題。

主指令對應這三個級別分別為:

1. work 指令,對應 工作級別的題目。
2. expert 指令,對應專業級別題目。
3. quiz 指令,對應 Quiz 級別題目。
4. anwser 指令,用來指定應該回答的問題數。

二、設定二級指令

接下來介紹一级指令,一级指令是可以和主指令組合使用:
1. `-tech` ,表示一级指令,代表要對其後指定的內容輸出相應主指令級別的概念講解,並附帶示例。
2. `-type` ,表示一级指令,代表要對其後指定的內容輸出相應主指令級別的題目。
3. `-idea`,表示一级指令,代表要輸出對應主指令級別的項目實踐想法和思路供人參考。
4. `-crate`,表示一级指令,代表要對其後指定的內容推薦相應的第三方 crate
5. `-n` ,表示一级指令, 代表你要給出答案的問題數目,並附上對答案的解釋。用到其他主指令的話,就是限制生成問題數量。

三、設定三級指令

接下來介紹二級指令,二級指令可作用於一级指令後面:
1. `--cn`,表示二級指令,代表以中文來輸出內容
2. `--en`,表示二級指令,代表以英文來輸出內容
3. `--jp`,表示二級指令,代表以日文來輸出內容

四、增加修改指令定義

之所以這麼費勁地設計這套指令系統,就是為了增加修改指令更加方便。否則,GPT-4 會亂套的。

下面是一个修改指令的示例:

修改一级指令:

`-n` ,表示一级指令, 代表你要給出答案的問題數目,並附上對答案的解釋。用到其他主指令的話,就是限制生成問題數量。

下面是一个增加指令的示例:

增加主指令:

explain , 表示對指定的 rust 代碼進行詳細的解釋
debug, 表示按給定的編譯器錯誤提示來幫助查找代碼bug並給出修正代碼

說明: explain 本身有解釋的意思,所以就算不這樣設置主指令,GPT 也能識別這個單詞。通常情況下 explain --cn 這種方式 GPT 也能識別 cn 並輸出中文。

使用方式:

debug 

fn add(a: i32, b: i32) -> i32 {
     (a + b) as i64
}

error:  返回類型不匹配

讓 GPT 輸出 “魔法” 系統說明書#

最後,讓 GPT 幫你把所有指令整理成一份表格:

請幫我把剛才設定的主指令,一级指令,二級指令,以及它們的功用,整合為一個markdown表格輸出給我

它就會輸出如下表格:

主指令功用
explain對指定的 Rust 代碼進行詳細的解釋
debug按給定的編譯器錯誤提示來幫助查找代碼 bug 並給出修正代碼
work輸出覆蓋 Rust 入門和日常編寫的常用特性和知識點的問題
expert輸出 Rust 專家級特性和知識點的問題
quiz輸出容易令人迷惑的 Rust 語言特性的題
anwser指定應該回答的問題數目,並附上對答案的解釋
一级指令功用
-tech輸出相應主指令級別的概念講解,並附帶示例
-type輸出相應主指令級別的題目
-idea輸出對應主指令級別的項目實踐想法和思路供人參考
-crate只限主指令 work 使用,推薦相應的第三方 crate
-n只限主指令 anwser 使用,指定要回答的問題數目,並附解釋
二級指令功用
--cn以中文來輸出內容
--en以英文來輸出內容
--jp以日文來輸出內容

“魔法” 系統使用效果#

現在我們的 “魔法” 系統就可以使用了,通過組合主指令、一级指令和二級指令可以達到我們期望的效果。

我們可以用它完成以下功能:

  • 生成不同級別的 Rust 題目和答案,可以考察自己的知識點
  • 可以指定 Rust 語言特性讓它生成對應的題目
  • 可以讓它推薦練手項目
  • 可以讓它回答自己生成的問題
  • 可以指定輸出內容的自然語言

生成 work 級別的題目#

work

GPT-4:

以下是兩道工作級別的 Rust 題目,一道選擇題和一道編寫代碼實現的題。

選擇題:

在 Rust 中,哪個關鍵字用於聲明一個不可變變量?
A. let
B. mut
C. const
D. static

編寫代碼實現題:

  1. 請編寫一個 Rust 函數 find_max,該函數接收一個整數向量作為參數,並返回向量中的最大值。如果向量為空,則返回 None。示例函數簽名如下:
fn find_max(numbers: Vec<i32>) -> Option<i32> {
    // 在此編寫你的代碼
}

生成 work 題目數量#

work -n 1

GPT-4:

GPT 理解 -n 是需要解釋題目的,這個可以通過修改指令進行修改。

以下是一道工作級別的 Rust 題目,一道選擇題:

選擇題:

  1. 在 Rust 中,哪個關鍵字用於聲明一個不可變變量?

A. let B. mut C. const D. static

答案: A. let

解釋: 在 Rust 中,使用 let 關鍵字聲明一個不可變變量。不可變意味著變量的值在聲明後無法更改。如果需要聲明一個可變變量,可以使用 let mut。而 conststatic 用於聲明常量,其中 const 是在編譯時確定的常量,static 是在運行時分配內存的全局變量。

按指定內容生成題目#

work -type algorithm

GPT-4:

以下是兩道與算法相關的工作級別 Rust 題目,一道選擇題和一道編寫代碼實現的題。

選擇題:

  1. 在 Rust 中,對於排序算法,以下哪個方法是對向量進行原地排序(即不創建新向量)?

A. sort B. sorted C. sort_by D. sort_unstable

編寫代碼實現題: 2. 請編寫一個 Rust 函數 merge_sorted_arrays,該函數接收兩個已排序的整數向量作為參數,並將它們合併為一個新的已排序向量。示例函數簽名如下:

fn merge_sorted_arrays(a: Vec<i32>, b: Vec<i32>) -> Vec<i32> {
    // 在此編寫你的代碼
}

為了防止 GPT-4 生成同樣的題目,可以讓它換題:

work -type trait change 

更換主指令為 expert

expert -type trait

GPT-4:

以下是兩道與 trait 相關的專業級別 Rust 題目,一道選擇題和一道編寫代碼實現的題。

選擇題:

  1. 在 Rust 中,關於 trait 對象和靜態分發,以下哪個說法是正確的?

A. trait 對象實現了靜態分發,性能優於動態分發 B. 靜態分發使用 trait 對象,性能優於動態分發 C. 靜態分發使用 monomorphization,在編譯時確定具體類型,性能優於動態分發 D. 動態分發使用 monomorphization,在編譯時確定具體類型,性能優於靜態分發

編寫代碼實現題: 2. 請實現一個名為 Drawable 的 trait,包含一個名為 draw 的方法。然後,請為 CircleRectangle 結構體實現 Drawable trait。最後,請創建一個包含 CircleRectangle 的向量,並通過調用 draw 方法遍歷繪製它們。示例代碼結構如下:

trait Drawable {
    // 在此編寫你的代碼
}

struct Circle {
    // 在此編寫你的代碼
}

struct Rectangle {
    // 在此編寫你的代碼
}

// 在此為 Circle 和 Rectangle 實現 Drawable trait

fn main() {
    // 在此創建 Drawable 向量,並通過調用 draw 方法遍歷繪製它們
}

指定只出 “編碼實現” 的題目:

work -n 1 -type ffi 編碼實現

以下是一道與 FFI(Foreign Function Interface)相關的工作級別 Rust 題目,為您提供一道編寫代碼實現的題以及答案和解釋。

編寫代碼實現題:

  1. 請使用 Rust 的 FFI 功能,編寫一個名為 rust_add 的函數,該函數將兩個 C 語言的 int 類型整數相加,並返回結果。請為此函數提供相應的 C 語言函數聲明。示例代碼結構如下:
// 在此編寫你的 Rust 代碼

/*
// 在此提供 C 語言函數聲明
extern "C" {
    // ...
}
*/

fn main() {
    // 在此編寫測試代碼
}

答案:

// Rust 代碼
#[no_mangle]
pub extern "C" fn rust_add(a: i32, b: i32) -> i32 {
    a + b
}

/*
// C 語言函數聲明
#include <stdint.h>

extern int32_t rust_add(int32_t a, int32_t b);
*/

fn main() {
    // 此處無法直接測試,需要在 C 語言環境中編譯並調用
}

解釋:首先,我們在 Rust 代碼中定義了一個名為 rust_add 的函數,該函數接受兩個 i32 類型的參數,並返回它們的和。為了讓 C 語言可以調用這個函數,我們需要使用 #[no_mangle] 屬性來禁止編譯器對函數名進行改寫。然後,我們使用 pub extern "C" 關鍵字指定這個函數的 ABI(Application Binary Interface)為 C 語言風格。

接下來,我們提供了 C 語言函數聲明。請注意,C 語言中的 int 類型在不同的平台和編譯器上可能具有不同的大小,所以我們在 C 語言中使用 int32_t 類型來確保與 Rust 中的 i32 類型相匹配。這需要包含 stdint.h 頭文件。

main 函數中,我們無法直接測試這個 FFI 函數,因為需要在 C 語言環境中編譯並調用。您可以創建一個簡單的 C 語言程序,將 Rust 編譯為動態庫或靜態庫,並鏈接到 C 語言程序中,然後調用 rust_add 函數進行測試。

我沒搞清楚,它為什麼有時候要帶解釋和答案。

推薦練手項目#

work -idea

GPT-4:

以下是一些 Rust 工作級別的項目實踐想法和思路供您參考:

  1. 命令行工具:創建一個用於處理日常任務的命令行工具,例如批量重命名文件、下載網絡資源或者解析日誌文件。可以使用 clapstructopt 庫來處理命令行參數。

  2. Web 服務器:使用 Rust 編寫一個簡單的多線程 Web 服務器,用於處理 HTTP 請求並提供靜態或動態內容。可以使用 hypertokio 庫來實現異步 I/O 和 HTTP 功能。

  3. 網絡爬蟲:編寫一個網絡爬蟲,從指定的網站抓取內容並解析出所需信息。可以使用 reqwest 庫來處理網絡請求,select.rs 庫來解析 HTML 文檔。

  4. 聊天服務器和客戶端:創建一個聊天服務器和客戶端,允許多個用戶通過 TCP 連接進行實時通信。可以使用 tokio 庫來實現異步 I/O 和多線程功能。

  5. 文件加密工具:實現一個簡單的文件加密和解密工具,用於保護用戶的隱私數據。可以使用 rust-cryptoring 庫來實現加密算法。

  6. 文本編輯器:開發一個簡單的文本編輯器,支持基本的文本編輯功能,如打開、保存、查找和替換。可以使用 crosstermtermion 庫來實現跨平台的終端界面。

可以指定 idea 關鍵字:

work -idea cli gpt

GPT-4:

以下是一個使用 Rust 開發的命令行界面 (CLI) GPT 工具的項目實踐想法和思路供您參考:

項目名稱:GPT-CLI

項目概述:創建一個命令行界面 (CLI) 工具,允許用戶通過輸入文本來與 GPT 模型進行交互,並獲得模型生成的文本。這個工具可以用於多種用途,如寫作輔助、編程問題解答、自动回复郵件等。

關鍵功能:

  1. 文本輸入:允許用戶輸入文本,以便將其作為 GPT 模型的輸入。
  2. GPT 模型集成:集成一個 GPT 模型(例如 OpenAI 的 GPT-3 或自行訓練的模型),並調用其 API 來生成基於用戶輸入的文本。
  3. 結果展示:將 GPT 模型生成的文本結果顯示給用戶。
  4. 保存功能:允許用戶將生成的文本結果保存到指定的文件中。

庫和工具建議:

  1. 命令行參數處理:使用 clapstructopt 庫來處理命令行參數。
  2. HTTP 請求庫:使用 reqwest 庫來處理與 GPT 模型 API 的網絡請求。
  3. 異步編程:使用 tokioasync-std 庫來實現異步編程,提高性能。
  4. 環境變量管理:使用 dotenv 庫來管理 API 密鑰等敏感信息。

開發步驟:

  1. 設計命令行參數結構,如輸入文本、保存文件路徑等。
  2. 使用 clapstructopt 庫解析命令行參數。
  3. 集成 GPT 模型 API,如 OpenAI GPT-3,設置 API 密鑰和請求參數。
  4. 使用 reqwest 庫發送 HTTP 請求,獲取 GPT 模型生成的文本結果。
  5. 處理 GPT 模型返回的結果,並將其顯示給用戶。
  6. 實現將生成的文本保存到文件的功能。
  7. 對程序進行測試和優化。

回答自己生成的問題#

expert -type struct

GPT-4:

以下是兩道與結構體相關的專業級別 Rust 題目,一道選擇題和一道編寫代碼實現的題。

選擇題:

  1. 在 Rust 中,關於結構體派生 PartialEqEq trait 的說法,哪個是正確的?

A. 所有結構體都必須實現 PartialEqEq trait B. 結構體只需實現 PartialEq trait,Eq trait 會自動派生 C. 結構體可以選擇派生 PartialEqEq trait,但前提是其所有字段都實現了這些 trait D. 結構體派生 PartialEqEq trait 時,不需要考慮其字段的 trait 實現

編寫代碼實現題: 2. 請創建一個名為 Color 的結構體,包含三個 u8 類型的字段:redgreenblue。為 Color 結構體實現 PartialEq trait,比較兩個 Color 實例是否相等。兩個 Color 實例相等的條件是:它們的 redgreenblue 字段值之差都小於等於 10。示例代碼結構如下:

use std::cmp::PartialEq;

struct Color {
    // 在此編寫你的代碼
}

impl PartialEq for Color {
    // 在此編寫你的代碼
}

fn main() {
    // 在此創建兩個 Color 實例,並比較它們是否相等
}
anwser -n 2

根據您的要求,我將為您提供前兩個問題的答案及解釋。

選擇題答案及解釋:

  1. 在 Rust 中,關於結構體派生 PartialEqEq trait 的說法,哪個是正確的?

答案:C. 結構體可以選擇派生 PartialEqEq trait,但前提是其所有字段都實現了這些 trait

解釋:在 Rust 中,結構體可以選擇性地為其派生 PartialEqEq trait,這允許您對結構體實例進行相等性比較。然而,派生這些 trait 的前提是結構體的所有字段都已經實現了這些 trait。如果結構體的某個字段沒有實現這些 trait,您將無法為該結構體派生 PartialEqEq trait。

編寫代碼實現題答案及解釋: 2. 請創建一個名為 Color 的結構體,包含三個 u8 類型的字段:redgreenblue。為 Color 結構體實現 PartialEq trait,比較兩個 Color 實例是否相等。兩個 Color 實例相等的條件是:它們的 redgreenblue 字段值之差都小於等於 10。示例代碼結構如下:

答案:

use std::cmp::PartialEq;

struct Color {
    red: u8,
    green: u8,
    blue: u8,
}

impl PartialEq for Color {
    fn eq(&self, other: &Self) -> bool {
        (self.red as i32 - other.red as i32).abs() <= 10 &&
        (self.green as i32 - other.green as i32).abs() <= 10 &&
        (self.blue as i32 - other.blue as i32).abs() <= 10
    }
}

fn main() {
    let color1 = Color { red: 255, green: 128, blue: 64 };
    let color2 = Color { red: 250, green: 130, blue: 70 };

    println!("Color1 equals Color2: {}", color1 == color2);
}

解釋:首先,我們定義了 Color 結構體,並為其添加了三個 u8 類型的字段:redgreenblue。接下來,我們為 Color 結構體實現了 PartialEq trait,並定義了 eq 方法。在 eq 方法中,我們比較了兩個 Color 實例的 redgreenblue 字段值之差的絕對值是否小於等於 10。如果滿足條件,那麼這兩個 Color 實例被認為是相等的。最後,在 main 函數中,我們創建了兩個 Color 實例,並使用 == 運算符比較它們是否相等。

推薦 crate#

expert -crate eBPF

GPT-4:

好的,以下是針對 eBPF 主題的專業級別題目以及推薦的第三方 crate:

題目:

  1. 請詳細介紹一下 eBPF 技術在 Rust 中的原理以及應用場景。
  2. 在 Rust 中,如何使用 libbpf-rs crate 編寫高效的 eBPF 程序?
  3. 在 Rust 中,如何使用 redbpf-probes crate 實現自定義的 eBPF 事件探針?

第三方 crate 推薦:

  • libbpf-rs:用於編寫和加載 eBPF 程序的 Rust crate。
  • redbpf-probes:用於編寫自定義 eBPF 事件探針的 Rust crate。

注意:eBPF 技術需要在支持它的內核上運行。如果您的系統不支持 eBPF,那麼您可能無法完成此任務。

可以指定輸出內容的自然語言#

要求它用日語輸出

work -tech lifetime --jp

GPT-4:

以下は、ライフタイムに関連する技術概念の説明と例を日本語で提供します。

ライフタイムとは、Rust でメモリ管理や参照の安全性を担保するための概念です。ライフタイムは、コンパイル時に参照の有効性を検証し、参照されるオブジェクトが参照されている期間中に破棄されないことを保証します。

例:

fn longest<'a>(s1: &'a str, s2: &'a str) -> &'a str {
    if s1.len() > s2.len() {
        s1
    } else {
        s2
    }
}

fn main() {
    let s1 = String::from("長い文字列");
    let s2 = String::from("短い");

    let result = longest(&s1, &s2);
    println!("最も長い文字列は: {}", result);
}

上記の例では、longest関数は 2 つの文字列のスライスを引数に取り、最も長いものを返します。ライフタイムパラメータ'aは、入力参照と戻り値の参照が同じライフタイムを持つことを示しています。

longest関数は、参照されるオブジェクトが参照されている期間中に破棄されないことを保証するために、ライフタイムを使用しています。これにより、ダングリングポインタや他のメモリ安全性に関連する問題を防止できます。

要求它用英文輸出:

work -tech --en lifetime

二級指令的位置不影響它理解

Below is an explanation and example of the technical concept of lifetimes in Rust, provided in English.

Lifetimes are a concept in Rust for managing memory and ensuring reference safety. Lifetimes are used to verify the validity of references at compile-time, ensuring that the object being referenced is not destroyed while it is still being referenced.

Example:

fn longest<'a>(s1: &'a str, s2: &'a str) -> &'a str {
    if s1.len() > s2.len() {
        s1
    } else {
        s2
    }
}

fn main() {
    let s1 = String::from("long string");
    let s2 = String::from("short");

    let result = longest(&s1, &s2);
    println!("The longest string is: {}", result);
}

In the example above, the longest function takes two string slices as arguments and returns the longer one. The lifetime parameter 'a indicates that the input references and the returned reference have the same lifetime.

The longest function uses lifetimes to ensure that the object being referenced is not destroyed while it is still being referenced, preventing dangling pointers and other memory safety-related issues.

小結#

這套 “魔法” 學習系統,設定起來並不困難,但是對日常學習 Rust 的幫助應該是巨大的。最後,希望大家能把你們自己擴展的好用的指令,或者值得記錄的 GPT-4 生成的 Rust 問題和解答都分享到 RustChat 的 GitHub 倉庫,形成一個問答知識庫來幫助更多的 Rust 學習者。

感謝閱讀。

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。