1. 什麼是切片
切片 (slice) 是一種不擁有資料所有權的型別,允許你借用集合(例如字串或陣列)中一段連續區間的內容。這和昨天學到的借用概念直接相關。
2. 字串切片 (String Slice)
字串切片用語法 [start..end],範圍是左閉右開 (start 包含,end 不包含)。
fn main() {
let s = String::from("hello world");
let hello = &s[0..5]; // 從 0 到 4
let world = &s[6..11]; // 從 6 到 10
println!("{} {}", hello, world);
}
輸出:
hello world
3. 省略寫法
如果切到字串開頭或結尾,可以省略範圍:
fn main() {
let s = String::from("hello");
let slice1 = &s[..2]; // 等同於 0..2
let slice2 = &s[3..]; // 等同於 3..len
let slice3 = &s[..]; // 整個字串
println!("{}, {}, {}", slice1, slice2, slice3);
}
輸出:
he, lo, hello
4. 陣列切片 (Array Slice)
切片不只適用於字串,也能用在陣列。
fn main() {
let arr = [1, 2, 3, 4, 5];
let slice = &arr[1..4]; // [2, 3, 4]
println!("{:?}", slice);
}
輸出:
[2, 3, 4]
5. 與函數搭配使用
切片常用來讓函數只接收部分資料而不是整個物件。
fn first_word(s: &String) -> &str {
let bytes = s.as_bytes();
for (i, &item) in bytes.iter().enumerate() {
if item == b' ' {
return &s[0..i];
}
}
&s[..]
}
fn main() {
let s = String::from("hello world");
let word = first_word(&s);
println!("first word: {}", word);
}
輸出:
first word: hello
這裡 &str 就是字串切片型別。
6. 借用規則與切片
有不可變切片存在時,不能同時取得可變借用:
fn main() {
let mut s = String::from("hello");
let part = &s[0..2]; // 不可變借用(切片)
// s.push('!'); // 編譯錯:同一時間不可同時有切片(不可變借用)與可變借用
println!("{}", part);
}
7. 學習心得與補充
今天學到切片,感覺它就像是借用的一部分,讓我不用複製資料也能安全地操作其中一段內容。這和昨天的借用很像,只是借用的是整個值,而切片則是值裡面的某個範圍。我覺得特別有趣的是,切片在字串和陣列都能用,而且語法簡潔,像 [start..end] 這種表示方式讓程式碼很直觀。這讓我回想到前幾天學的所有權和 .clone(),以前我可能會用複製來處理部分資料,但現在發現其實用切片就可以避免不必要的深拷貝。一步一步學下來,變數的不可變性、借用、切片慢慢串起來,讓我覺得 Rust 雖然規則多,但設計真的很有一致性。