CodeToLive

Ownership and Borrowing in Rust

Ownership is a key concept in Rust that ensures memory safety. Each value in Rust has a variable that owns it, and there can only be one owner at a time. Borrowing allows you to reference a value without taking ownership.

Ownership Rules

Rust's ownership rules are as follows:

Example: Ownership Transfer


fn main() {
    let s1 = String::from("hello");
    let s2 = s1;  // Ownership of the string is transferred to s2
    // println!("{}", s1);  // This would cause a compile-time error
    println!("{}", s2);  // s2 is now the owner
}
      

Borrowing and References

Borrowing allows you to reference a value without taking ownership. You can have either one mutable reference or multiple immutable references at a time.


fn main() {
    let s1 = String::from("hello");
    let len = calculate_length(&s1);  // Pass a reference to s1
    println!("Length of '{}' is {}.", s1, len);

    let mut s2 = String::from("world");
    change_string(&mut s2);  // Pass a mutable reference to s2
    println!("Changed string: {}", s2);
}

fn calculate_length(s: &String) -> usize {
    s.len()
}

fn change_string(s: &mut String) {
    s.push_str("!");
}
      

Slices

Slices allow you to reference a contiguous sequence of elements in a collection.


fn main() {
    let s = String::from("hello world");
    let hello = &s[0..5];  // Slice from index 0 to 5
    let world = &s[6..11]; // Slice from index 6 to 11
    println!("{} {}", hello, world);
}
      

Lifetime Annotations

Lifetimes ensure that references are valid for as long as they are used. Rust's borrow checker enforces these rules at compile time.


fn main() {
    let string1 = String::from("long string is long");
    let string2 = String::from("xyz");
    let result = longest(string1.as_str(), string2.as_str());
    println!("The longest string is {}", result);
}

fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
    if x.len() > y.len() {
        x
    } else {
        y
    }
}
      

Interactive Code Examples

Try running these examples in your Rust environment to see how they work!


// Interactive Example
fn main() {
    let s1 = String::from("hello");
    let s2 = s1;  // Ownership is transferred to s2
    println!("{}", s2);
}
      

Practice Problems

Test your understanding with these practice problems:

  1. Write a Rust function that takes a string slice and returns the first word.
  2. Write a Rust program that demonstrates the difference between mutable and immutable references.
  3. Write a Rust function that takes two string slices and returns the longer one.
Back to Tutorial