CS 245 - Programming Languages

Lab 8

Rust ownership and borrowing

In this lab you will write / analyze small programs in Rust involving mutability, borrowing and ownership.

Exercise 1

1    fn main() {
2        let mut list = vec![1, 2, 3];
3        println!("Before defining closure: {:?}", list);
4        let mut borrows_mutably = || list.push(7);
5        println!("{:?}", list); 
6        borrows_mutably();
7        println!("After calling closure: {:?}", list);
8    }
The above program will not compile (line numbers appear for easy reference). But removing line 5 allows the program to not only compile, but run too! Explain. In particular, what is going on with line 4?

Exercise 2

    fn main() {
        let vec0 = vec![22, 44, 66];
        let vec1 = fill_vec(vec0);
        println!("{:?}", vec0);
    }
    
    fn fill_vec(vec: Vec) -> Vec {
        let vec = vec;
        vec.push(88);
        vec
    }
Make the smallest possible change to this program so that it prints [22,44,66,88] Explain why your change works

Exercise 3

    fn main() {
        let vec0 = vec![22, 44, 66];
        let mut vec1 = fill_vec(vec0);
        println!("{:?}",vec1);
    }
    
    fn fill_vec(vec: Vec) -> Vec {
        vec.push(88);
        vec
    }
Change the code so that it compiles and produces the output "[22,44,66,88]". Your change should NOT add any lines to the code.

Exercise 4

    fn main() {
        let vec0 = vec![22, 44, 66];
        let vec1 = fill_vec(vec0);
        println!("{:?}",vec1);
    }
    
    // `fill_vec()` no longer takes `vec: Vec` as argument - don't change this!
    fn fill_vec() -> Vec {
        let mut vec = vec;
        vec
    }
Change this code so it produces the output "[22,44,66,88]". Only change code within the fill_vec function.

Exercise 5

Change each of the print statements in the code below so that they show the value of everything that is printable.
    fn main() {
        let s1 = vec![1,2,3];
        let mut s2 = vec![4,5,6];
        println!("A ..");
        g_o(s1);
        println!("B .."); 
        t_a_g(&mut s2);
        println!("E ..");
    } 
    
    fn g_o(mut aa : Vec)  {             
        aa[0]=4;
        println!("C ", aa);       
    }
    
    fn t_a_g(aa : &mut Vec) { 
        aa[0]=42;
        println!("D ", aa);       
    
    }
    
What is the output of the each of the print statements?

What to hand in

Work no more than 80 minutes on the above programs. If you did not complete everything, send what you have.

Send email to gtowell@brynmawr.edu with all three programs. (Or as far as you got.)