建議讀者在閱讀本文之前,先學習《提示指南》(https://www.promptingguide.ai/zh),以便更好地理解。也建議使用 GPT-4 來創建此系統,但如果無法使用 GPT-4,也可以使用 GPT-3.5 來創建此系統,雖然 GPT-4 更為準確。此外,該系統還可以應用於其他編程語言。
最近,我一直在嘗試 ChatGPT 和 Midjourney 等 AI 技術,試圖體驗成為一名年薪六位數的提示工程師的感覺。直到本週,我才發現 GPT-4 對學習 Rust 代碼是多麼有幫助。因此,我嘗試創建這個 Rust 學習系統,我將其命名為 "RustChat" (https://github.com/ZhangHanDong/rustchat),並在 GitHub 上創建了一個庫,供其他人參與。
在學習 Rust 時,擁有一個可以提供問題以測試我們知識並給出準確答案和解釋的系統將是非常好的。或者,當我們不知道該做什麼項目來練習時,它可以推薦項目想法。現在,借助 AI,我們可以創建這樣一個神奇而有用的系統。
RustChat 介紹:終極 Rust 學習 "魔法" 系統#
首先,讓我們談談這個想法。由於我們想要一個命令提示模式,我們應該像設計程序 API 一樣設計命令格式。
值得注意的是,雖然這個想法看起來很簡單,但它是大量實驗的結果。之前失敗的設計導致一個新命令破壞了舊的 GPT 設置,造成了混淆。
"魔法" 設計#
以下是我想實現的一些命令提示示例:
work // "work" 是主要命令,代表工作層級的 Rust 問題
work -tech trait // "-tech" 代表一個主要命令,意味著為指定的 "trait" 內容輸出工作層級概念解釋並提供代碼示例
work -tech --cn trait // "--cn" 代表一個次要命令,意味著以中文輸出主要命令和主要命令指定的內容
work -type --en eBPF // "-type" 代表一個主要命令,意味著為指定內容 "eBPF" 輸出工作層級問題
work -idea --cn // "-idea" 代表一個主要命令,意味著輸出對應於主要命令層級的項目實踐想法和思考供參考。 "--cn" 代表一個次要命令,意味著以中文輸出內容。
我計劃將問題分為三個層級:
- 工作層級。工作層級問題涵蓋編寫 Rust 代碼的基本和常見特徵及知識。
- 專業層級。專業層級涵蓋 Rust 的專家級特徵和知識。
- 測驗類型。測驗類型專門設計用於測試 Rust 語言中容易混淆的特徵。
主要命令分別對應於這三個層級:
- "work" 命令對應於工作層級問題。
- "expert" 命令對應於專業層級問題。
- "quiz" 命令對應於測驗層級問題。
- "answer" 命令用於指定要回答的問題數量。
接下來,讓我們介紹主要命令。主要命令可以與主要命令以任何方式組合:
- "-tech" 代表一個主要命令,意味著為指定內容輸出對應的主要命令層級概念解釋並提供示例。
- "-type" 代表一個主要命令,意味著為指定內容輸出對應的主要命令層級問題。
- "-idea" 代表一個主要命令,意味著輸出對應於主要命令層級的項目實踐想法和思考供參考。
- "-crate" 代表一個主要命令,僅適用於 "work" 命令,意味著為指定內容推薦對應的第三方 "crate"。
- "-n" 代表一個主要命令,僅適用於 "answer" 命令,意味著指定要回答的問題數量。
接下來,讓我們介紹次要命令,可以在主要命令之後使用:
- "--cn" 代表一個次要命令,意味著以中文輸出內容。
- "--en" 代表一個次要命令,意味著以英文輸出內容。
- "--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" 代表一個次要命令,意味著以中文輸出內容。
answer -n 2 ,// "-n" 代表一個主要命令,僅適用於 "answer" 命令,意味著回答此命令之前的兩個問題
expert // "expert" 是主要命令,代表專業層級的 Rust 問題
expert -tech trait // "-tech" 代表一個主要命令,意味著為指定的 "trait" 內容輸出專業層級概念解釋並提供代碼示例
expert -tech --cn trait // "--cn" 代表一個次要命令,意味著以中文輸出主要命令和主要命令指定的內容
expert -type --en eBPF // "-type" 代表一個主要命令,意味著為指定內容 "eBPF" 輸出專業層級問題
expert -idea --cn // "-idea" 代表一個主要命令,意味著輸出對應於主要命令層級的項目實踐想法和思考供參考。 "--cn" 代表一個次要命令,意味著以中文輸出內容。
quiz // "quiz" 是主要命令,代表 Rust 測驗問題
quiz -tech trait // "-tech" 代表一個主要命令,意味著為指定的 "trait" 內容輸出測驗層級概念解釋並提供代碼示例
quiz -tech --cn trait // "--cn" 代表一個次要命令,意味著以中文輸出主要命令和主要命令指定的內容
quiz -type --en eBPF // "-type" 代表一個主要命令,意味著為指定內容 "eBPF" 輸出測驗層級問題
quiz -idea --cn // "-idea" 代表一個主要命令,意味著輸出對應於主要命令層級的項目實踐想法和思考供參考。 "--cn" 代表一個次要命令,意味著以中文輸出內容。
構建提示#
接下來,我們將構建一個提示。為了確保 GPT-4 能夠充分理解設計的 "魔法",我們應該採用 "整體到細節" 的方法逐步 "餵" 它。
1. 設定主要命令
作為 Rust 專家,我需要你的幫助根據我的要求生成 Rust 問題。默認情況下,問題包括一個選擇題和一個編碼問題。默認情況下,問題以中文輸出,除非指定了相應的次要命令來告訴你問題的數量。
問題分為三個層級:
1. 工作層級。工作層級問題涵蓋初學者和日常使用的 Rust 代碼編寫的常見特徵和知識。
2. 專家層級。專家層級涵蓋 Rust 專家的特徵和知識。
3. 測驗類型。測驗類型專門測試 Rust 語言中容易混淆的特徵。
主要命令分別對應於這三個層級:
1. "work" 命令,對應於工作層級問題。
2. "expert" 命令,對應於專家層級問題。
3. "quiz" 命令,對應於測驗層級問題。
4. "anwser" 命令,用於指定要回答的問題數量。
2. 設定主要命令
接下來,讓我們介紹主要命令,可以與主要命令組合使用:
1. "-tech",代表一個主要命令,意味著應該為指定內容輸出對應的主要命令層級概念解釋,並附上示例。
2. "-type",代表一個主要命令,意味著應該為指定內容輸出對應的主要命令層級問題。
3. "-idea",代表一個主要命令,意味著應該為參考輸出對應於主要命令層級的項目實踐想法和策略。
4. "-crate",代表一個主要命令,意味著應該為指定內容推薦對應的第三方 crate。
5. "-n",代表一個主要命令,意味著需要指定要回答的問題數量並提供答案的解釋。如果使用其他主要命令,則限制生成的問題數量。
3. 設定次要命令
接下來,讓我們介紹次要命令,可以在主要命令之後使用:
1. "--cn",代表一個次要命令,意味著應該以中文輸出內容。
2. "--en",代表一個次要命令,意味著應該以英文輸出內容。
3. "--jp",代表一個次要命令,意味著應該以日文輸出內容。
- 添加修改命令的定義
設計這個命令系統如此詳細的原因是為了使添加和修改命令更加方便。否則,GPT-4 會感到困惑。
以下是修改命令的示例:
修改主要命令:
"-n",代表一個主要命令,意味著需要指定要回答的問題數量並提供答案的解釋。如果使用其他主要命令,則限制生成的問題數量。
以下是添加指令的示例:
添加主要指令:解釋,意味著提供指定 Rust 代碼的詳細解釋。調試,意味著幫助查找代碼錯誤並根據給定的編譯器錯誤提示提供修正的代碼。
注意:
解釋
本身就有解釋的意思,因此即使未設置此主要指令,GPT 也能識別此單詞。在大多數情況下,GPT 也可以識別cn
並使用解釋 --cn
輸出中文。
用法:
debug
fn add(a: i32, b: i32) -> i32 {
(a + b) as i64
}
error: 返回類型不匹配
讓 GPT 輸出 "魔法" 系統手冊#
最後,讓 GPT 幫助你將所有指令整理成一個 markdown 表格:
請幫我將主要、次要和次要指令及其功能整理成一個 markdown 表格。
它將輸出以下表格:
主要指令 | 功能 |
---|---|
解釋 | 提供指定 Rust 代碼的詳細解釋。 |
調試 | 幫助查找代碼錯誤並根據給定的編譯器錯誤提示提供修正的代碼。 |
work | 輸出涵蓋 Rust 的常見特徵和知識的問題,適用於入門和日常編程。 |
expert | 輸出涵蓋 Rust 專家級特徵和知識的問題。 |
quiz | 輸出專門測試 Rust 語言特徵的問題,這些特徵容易混淆。 |
anwser | 指定要回答的問題數量並提供答案的解釋。 |
次要指令 | 功能 |
---|---|
-tech | 輸出對應的主要指令層級概念解釋及示例。 |
-type | 輸出對應的主要指令層級問題。 |
-idea | 輸出對應於主要指令層級的項目實踐想法和思考。 |
-crate | 僅限於 work 主要指令,推薦對應的第三方 crates。 |
-n | 僅限於 anwser 主要指令,指定要回答的問題數量並提供解釋。 |
次要指令 | 功能 |
---|---|
--cn | 以中文輸出內容。 |
--en | 以英文輸出內容。 |
--jp | 以日文輸出內容。 |
"魔法" 系統用法#
現在,我們的 "魔法" 系統已經啟動並運行,我們可以通過結合主要指令、第一級指令和第二級指令來實現預期的結果。
我們可以用它來實現以下功能:
- 生成不同層級的 Rust 問題和答案以測試我們的知識
- 指定 Rust 語言特徵以生成相應的問題
- 讓它推薦實踐項目
- 讓它回答我們自己生成的問題
- 指定輸出內容的自然語言
生成工作層級問題#
work
GPT-4:
這裡有兩個工作層級的 Rust 問題,一個選擇題和一個編碼問題。
選擇題:
在 Rust 中,哪個關鍵字用於聲明不可變變量? A. let B. mut C. const D. static
編碼問題:2. 請編寫一個 Rust 函數 find_max
,該函數接受一個整數向量作為參數,並返回向量中的最大值。如果向量為空,則返回 None。函數簽名如下:
fn find_max(numbers: Vec<i32>) -> Option<i32> {
// 在這裡編寫你的代碼
}
生成指定數量的工作層級問題#
複製代碼
work -n 3
GPT-4:
GPT 理解
-n
需要問題的解釋,這可以通過指令定義進行修改。
這裡有三個工作層級的 Rust 問題,每個問題由一個選擇題和一個編碼實現問題組成:
問題 1:
在 Rust 中,哪個關鍵字用於聲明不可變變量?
A. let B. mut C. const D. static
答案:A. let
解釋:在 Rust 中,使用 let
關鍵字聲明不可變變量。不可變意味著變量的值在聲明後不能更改。如果需要聲明可變變量,可以使用 let mut
。const
和 static
關鍵字用於聲明常量,其中 const
是編譯時常量,而 static
是在運行時全局分配的變量。
問題 2:
編寫一個名為 calculate_average
的 Rust 函數,該函數接受一個整數向量作為輸入,並返回這些數字的平均值。如果向量為空,則返回 None。函數簽名應如下所示:
rust 複製代碼
fn calculate_average(numbers: Vec<i32>) -> Option<f32> { // 在這裡編寫你的代碼 }
問題 3:
在 Rust 中,String
和 &str
之間的區別是什麼?
A. String
是固定大小的字符串,而 &str
是可變大小的字符串。 B. String
是不可變字符串,而 &str
是可變字符串。 C. String
是堆分配的字符串,而 &str
是堆棧分配的字符串。 D. String
是擁有的字符串,而 &str
是借用的字符串。
答案:D. String
是擁有的字符串,而 &str
是借用的字符串。
解釋:在 Rust 中,String
是一種類型,表示一個堆分配的、可增長的、可變的 Unicode 字符序列。&str
是對字符串切片的引用,這是一個固定大小的視圖,包含一系列 Unicode 標量值的內存塊。String
擁有它所使用的內存,而 &str
則從其他來源借用內存。
根據指定內容生成問題#
work -type algorithm
GPT-4:
這裡有兩個與算法相關的 Rust 工作層級問題,一個選擇題和一個編碼問題。
選擇題:
- 在 Rust 中,哪個方法用於對向量進行就地排序(即不創建新向量)以進行排序算法?
A. sort B. sorted C. sort_by D. sort_unstable
編碼問題:
- 請編寫一個 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:
這裡有兩個與 traits 相關的 Rust 工作層級問題,一個選擇題和一個編碼問題。
選擇題:
- 在 Rust 中,關於 trait 對象和靜態調度的說法哪個是正確的?
A. Trait 對象實現靜態調度,並且比動態調度性能更好。 B. 靜態調度使用 trait 對象,並且比動態調度性能更好。 C. 靜態調度使用單型化在編譯時確定具體類型,從而比動態調度性能更好。 D. 動態調度使用單型化在編譯時確定具體類型,從而比靜態調度性能更好。
編碼問題:
- 請實現一個名為
Drawable
的 trait,該 trait 包含一個名為draw
的方法。然後,為Circle
和Rectangle
結構實現Drawable
trait。最後,創建一個包含Circle
和Rectangle
的向量,並通過遍歷該向量並調用draw
方法來繪製它們。示例代碼結構如下:
trait Drawable {
// 在這裡編寫你的代碼
}
struct Circle {
// 在這裡編寫你的代碼
}
struct Rectangle {
// 在這裡編寫你的代碼
}
// 在這裡為 Circle 和 Rectangle 實現 Drawable trait
fn main() {
// 在這裡編寫你的代碼以創建 Drawable 向量並通過調用 draw 方法繪製它們
}
answer -n 2
根據您的要求,我將為前兩個問題提供答案和解釋。
選擇題答案和解釋:
- 在 Rust 中,關於 deriving
PartialEq
和Eq
traits 的說法哪個是正確的?
答案:C. 結構可以選擇性地衍生 PartialEq
和 Eq
traits,但只有當它們的所有字段都實現這些 traits 時。
解釋:在 Rust 中,結構可以選擇性地衍生 PartialEq
和 Eq
traits 以進行結構實例的相等比較。然而,衍生這些 traits 的前提是它的所有字段都已經實現了這些 traits。如果結構的任何字段未實現這些 traits,則無法為該結構衍生 PartialEq
和 Eq
traits。
編碼問題的答案和解釋:
- 請創建一個名為
Color
的結構,該結構包含三個u8
字段:red
、green
和blue
。為Color
結構實現PartialEq
trait,以比較兩個Color
實例是否相等。如果兩個Color
實例的red
、green
和blue
字段值之間的差異小於或等於 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
類型的字段:red
、green
和 blue
。接下來,我們為 Color
結構實現了 PartialEq
trait,並定義了 eq
方法。在 eq
方法中,我們比較兩個 Color
實例的 red
、green
和 blue
字段的絕對差異,看看它們是否小於或等於 10。如果滿足此條件,則認為這兩個 Color
實例相等。最後,在 main
函數中,我們創建了兩個 Color
實例,並使用 ==
操作符比較它們是否相等。
推薦的 crate#
expert -crate eBPF
GPT-4:
好的,這裡有一些與 eBPF
主題相關的高級問題和推薦的第三方 crates:
問題:
- 請詳細解釋 Rust 中 eBPF 技術的原理和應用場景。
- 在 Rust 中,如何使用
libbpf-rs
crate 編寫高效的 eBPF 程序? - 在 Rust 中,如何使用
redbpf-probes
crate 實現自定義 eBPF 事件探針?
推薦的第三方 crates:
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
次要指令的位置不會影響其理解。
以下是對 Rust 中生命週期的技術概念的解釋和示例,提供英文版本。
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 問題和答案,將其形成一個 Q&A 知識庫,以幫助更多的 Rust 學習者。
感謝您的閱讀。