iT邦幫忙

0

二、三天學一點點 Rust:來! 擁有權Ownership之二(18)

  • 分享至 

  • xImage
  •  

🧠 Copy Trait 與 String 型別的差異

Rust 有一個稱為 Copy 的 trait。Trait 在 Rust 中定義了共享的行為。如果一個型別實作了 Copy trait,將它的值賦給一個新的變數將會產生一個位元組層級的副本。這意味著表示該值的位元被複製了。原始變數和新變數在賦值後都是獨立有效的。以下列程式碼來說明。

fn main() {
    let time = 2025;
    let year = time;
    println!("The time is {}. It is year {}.", time, year);
}

✅ 整數型別與 Copy Trait

在第一段程式中:

let time = 2025;
let year = time;

這裡的 time 是一個整數(i32,預設整數型別),它實作了 Rust 的 Copy trait

這代表:

  • year = time 時,資料會被複製一份
  • timeyear 都可以在之後繼續使用。

🔍 Copy 型別特性整理

特性 說明
所屬 trait Copy
複製方式 位元複製(bitwise copy)
會不會 move? ❌ 不會,原變數還可以使用
常見型別 i32, u32, bool, char, f64
需要實作 Drop? ❌ 不能和 Drop 同時存在

📚 參考文件:Copy Trait - Rust Docs


📦 String 型別:堆積記憶體與所有權轉移

String 是 Rust 的可增長的、在堆積上分配記憶體的字串型別。實際的文字資料儲存在堆積上。String 變數本身保存著指向這個堆積資料的指標,以及容量和長度等資訊。

在程式的下半段:

let text = String::new();
let name = String::from("Roger");

String 是一種堆積(heap)型別,它儲存的資料位於 Heap 上,並且擁有動態長度,因此它不實作 Copy trait。當你把一個 String 指派給另一個變數時,會觸發 Rust 的所有權系統:

  • 預設是「所有權轉移(move)」,不是複製
  • 原本的變數會失效,避免重複釋放記憶體(Double Free)

以下說明一下這兩個常用語法:
String::new() 會創建一個新的、空的 String。  
這意味著它會在堆積上分配一塊記憶體,用於儲存字串的內容,但一開始這塊記憶體中沒有任何字元。
你可以將 String::new() 創建的 String 想像成一個空的盒子,這個盒子可以隨著你放入更多的字元而擴大。

String::from("Roger") 會創建一個新的 String,並且會將字串字面值 "Roger" 的內容複製到這個 String 中。這意味著它也會在堆積上分配一塊記憶體,但是這塊記憶體一開始就包含了 "Roger" 這五個字元。
你可以將 String::from("Roger") 創建的 String 想像成一個已經裝有 "Roger" 這個詞的盒子。

🔍 String 特性整理

特性 說明
是否實作 Copy? ❌ 否
是否 move? ✅ 是,預設移動所有權
記憶體位置 堆積(heap)
型別特徵 可變長度、擁有所有權、帶有 Drop 實作

✅ 小結:Copy vs Move 的關鍵差異

比較項目 Copy 型別(如 i32) 非 Copy 型別(如 String)
複製方式 複製資料(bitwise) 移轉所有權
原變數還能用? ✅ 是 ❌ 否,會失效
會 drop 資源? ❌ 否 ✅ 是
儲存位置 Stack Stack + Heap(資料在 Heap)

🧠 push_str 與擁有權(Ownership)

本篇教學將透過以下簡單的程式碼,說明 push_str() 方法的使用,並結合 Rust 的所有權(ownership)概念進行解釋。

fn main() {
    let mut name = String::from("Roger");
    println!("{}", name);

    name.push_str(" Chen.");
    println!("{}", name);
}

✅ 程式說明:動態字串與可變性

  1. String 是一種在堆積(heap)上儲存可變長度字串的資料結構。這意味著字串的實際內容(例如 "Roger" 或 "Roger Chen.")儲存在堆積記憶體中。
  2. String 變數本身(例如 name)儲存在堆疊(stack)上,它包含指向堆積中字串內容的指標、長度和容量等資訊。
  3. 每個 String 都有一個「擁有者」(owner)。在這個練習題中,name 變數是它所儲存的字串資料的所有者。
  4. 擁有者負責在不再需要字串資料時釋放它。  

🔧 push_str() 方法簡介

push_str 方法用於將一個字串片段(&str)附加到現有的 String 的末尾。關鍵在於,push_str 方法會直接修改 String 的內容,而不會創建一個新的 String。以下以表格說明。

方法 說明
push_str() 用來將一個 &str(字串切片)附加到 String 之後
所需權限 需要可變的 String 變數(即 mut
所有權關係 push_str 不會取得字串的所有權,只是修改內容
被加入的字串 必須是 &str,不會被移動

🧠 所有權觀念補充

  • String 是一個擁有堆積記憶體的型別
  • 使用 mut 是讓你可以「修改這個擁有者持有的資料」。
  • 在這段程式碼中,name 一直保有對字串資料的所有權,並透過 push_str 修改內容。

✅ 重點:push_str 修改的是「擁有的內容」,而不是把所有權轉移給別人。


🔍 輸出結果:

Roger
Roger Chen.

這代表原變數 name 經過 push_str 後內容已更新,並且仍然擁有該 String


這個練習說明了 Rust 如何透過所有權和可變性,安全地操作堆積資料。


圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言