Activity 17 - Be the Borrow Checker!
For each code snippet below:
- Circle each borrow
- Draw a box or bracket around each borrow's scope (from creation to last use)
- Label each borrow scope as
&(immutable) or&mut(mutable) - Mark any conflicts where borrows violate the rules
- Decide whether the code will compile or not (and if not, why not)
Borrow Checker Rules:
- Rule 1: You can have EITHER many immutable references OR one mutable reference (not both)
- Rule 2: References must be valid (can't outlive the data they point to)
Problem 1 - let's do it together
fn main() { let mut scores = vec![85, 92, 78]; let reader = &scores; println!("Current scores: {:?}", reader); let writer = &mut scores; writer.push(95); println!("Updated scores: {:?}", writer); }
Problem 2
fn main() { let data = vec![1, 2, 3]; let ref1 = &data; let ref2 = &data; let ref3 = &data; println!("{:?}", ref1); println!("{:?}", ref2); println!("{:?}", ref3); println!("{:?}", data); }
Problem 3
fn main() { let mut numbers = vec![1, 2, 3, 4, 5]; for num in numbers.iter() { println!("{}", num); let num_ref = &mut numbers; num_ref.push(*num * 2); } }
Fun (and useful) fact - the same thing happens when you do numbers.push() without let ...
Problem 4
fn main() { let mut text = String::from("Hello"); let read = &text; println!("{}", read); let write = &mut text; write.push_str(" World"); println!("{} {}", read, write); }
Problem 5
fn main() { let mut data = vec![10, 20, 30]; let sum = calculate_sum(&data); add_bonus(&mut data, 5); println!("Sum: {}, Data: {:?}", sum, data); } fn calculate_sum(numbers: &Vec<i32>) -> i32 { numbers.iter().sum() } fn add_bonus(numbers: &mut Vec<i32>, bonus: i32) { for num in numbers.iter_mut() { *num += bonus; } }
Problem 6
fn main() { let outer; // this creates the variable at this scope and lets you set it to a value later { let inner = vec![1, 2, 3]; outer = &inner; println!("Inside: {:?}", outer); } println!("Outside: {:?}", outer); }
Problem 7
fn main() { let mut values = vec![1, 2, 3]; let modifier1 = &mut values; modifier1.push(4); println!("After first: {:?}", modifier1); let modifier2 = &mut values; modifier2.push(5); println!("After second: {:?}", modifier2); }
Problem 8
fn create_message() -> &String { let msg = String::from("Hello"); return &msg; } fn main() { let message = create_message(); println!("{}", message); }
Problem 9
fn main() { let mut data = vec![1, 2, 3]; let first = &data[0]; data.push(4); println!("First element: {}", first); }