Vec and String
Vec<T> — Growable Heap Array
Section titled “Vec<T> — Growable Heap Array”Vec<T> is Rust’s workhorse sequential collection. It stores elements of type T contiguously on the heap and automatically resizes when you push beyond its current capacity.
let mut v: Vec<i32> = Vec::new(); // empty Veclet w = vec![1, 2, 3]; // vec! macro shorthandPushing, Popping, and Indexing
Section titled “Pushing, Popping, and Indexing”let mut v = vec![10, 20, 30];
v.push(40); // append an elementlet last = v.pop(); // remove and return the last element → Some(40)let first = v[0]; // index — panics if out of boundslet safe = v.get(100); // returns Option<&T> — None if out of boundsPrefer .get(i) when the index might be out of range so you handle the None case instead of panicking.
Iterating Over a Vec
Section titled “Iterating Over a Vec”let nums = vec![1, 2, 3];
for n in &nums { // borrow each element as &i32 println!("{}", n);}
// nums is still valid after the loop because we only borrowed itUsing &nums borrows the vector; using nums would move it and make it unavailable after the loop.
String — Owned, Growable Text
Section titled “String — Owned, Growable Text”String is Rust’s heap-allocated, mutable text type. It owns its bytes and manages deallocation.
let mut s = String::from("hello");s.push(' '); // push a single chars.push_str("world"); // append a string slicelet combined = s + " again"; // + moves s and appendsString vs &str
Section titled “String vs &str”String | &str | |
|---|---|---|
| Ownership | Owned | Borrowed slice |
| Location | Heap | Stack / static / inside a String |
| Mutable | Yes (with mut) | No |
| Typical use | Building/modifying text | Reading text |
A &String automatically coerces to &str, so prefer &str in function parameters for maximum flexibility.
fn shout(s: &str) -> String { s.to_uppercase()}
let owned = String::from("hello");shout(&owned); // &String coerces to &strshout("world"); // string literal is already &strfn main() { // Vec<i32> basics let mut nums: Vec<i32> = Vec::new(); nums.push(10); nums.push(20); nums.push(30); println!("len={}, first={}", nums.len(), nums[0]);
// pop returns Option<T> let last = nums.pop(); println!("popped: {:?}, remaining: {:?}", last, nums);
// safe get returns Option<&T> println!("get(5) = {:?}", nums.get(5));
// iterate by reference — nums still valid after for n in &nums { println!("item: {}", n); } println!("nums still valid: {:?}", nums);
// String vs &str let literal: &str = "hello"; let mut owned: String = String::from(literal); owned.push_str(" world"); println!("{}", owned);
// slice into a String let slice: &str = &owned[0..5]; println!("slice: {}", slice);}Compiling…