codingstuff.io
ExploreTutorialsProblemsCS Subjects
Get Started
ExploreTutorialsProblemsCS Subjects
Get Started
codingstuff.io

Master the art of building software through interactive tutorials, real-world problems, and guided projects.

Pune, Maharashtra, India

codingstuffmail@gmail.com

Product

  • Explore
  • Tutorials
  • Problems
  • CS Subjects

Company

  • About
  • Contact
  • Privacy Policy
  • Terms & Conditions
  • Sitemap

© 2026 codingstuff.io. All rights reserved.

Built with ❤️ for developers everywhere

/
/
All Tutorials
🦀

Rust

14 / 58 topics
13Ownership14Borrowing15References16Slices
Tutorials/Rust/Borrowing
🦀Rust

Borrowing

Updated 2026-05-15
10 min read

Borrowing

Introduction

In Rust, the concept of borrowing is a fundamental part of its ownership model. It allows you to share access to data without transferring ownership. This tutorial will cover the rules and lifetimes associated with borrowing in Rust, providing both theoretical understanding and practical examples.

Concept

Borrowing in Rust is managed through references (&). References allow you to refer to some value without taking ownership of it. There are two types of references:

  1. Immutable References (&T): These allow multiple immutable borrows at the same time, but no mutable borrow can exist simultaneously.
  2. Mutable References (&mut T): These allow a single mutable borrow at a time, and no other borrows (immutable or mutable) can exist simultaneously.

The key rule of borrowing is that you cannot have both mutable and immutable references to the same data in the same scope. This ensures memory safety without needing a garbage collector.

Examples

Immutable Borrowing

Let's start with an example of immutable borrowing:

Rust
1fn main() {
2 let s1 = String::from("hello");
3
4 let len = calculate_length(&s1);
5
6 println!("The length of '{}' is {}.", s1, len);
7}
8
9fn calculate_length(s: &String) -> usize {
10 s.len()
11}

In this example:

  • &s1 creates an immutable reference to s1.
  • The function calculate_length takes a reference to a String and returns its length.
  • Since we only have immutable references, the original s1 remains valid after the function call.

Mutable Borrowing

Now, let's see how mutable borrowing works:

Rust
1fn main() {
2 let mut s = String::from("hello");
3
4 change(&mut s);
5
6 println!("The modified string is '{}'.", s);
7}
8
9fn change(s: &mut String) {
10 s.push_str(", world!");
11}

In this example:

  • &mut s creates a mutable reference to s.
  • The function change takes a mutable reference and modifies the string.
  • Since we have a mutable reference, no other references (immutable or mutable) can exist in the same scope.

Mixing Immutable and Mutable References

Rust enforces strict rules about mixing immutable and mutable references. Here's an example that will cause a compile-time error:

Rust
1fn main() {
2 let mut s = String::from("hello");
3
4 let r1 = &s; // no problem
5 let r2 = &s; // no problem
6 let r3 = &mut s; // BIG PROBLEM
7
8 println!("{} and {}", r1, r2);
9 println!("{}", r3);
10}

In this example:

  • r1 and r2 are immutable references to s, which is allowed.
  • However, creating a mutable reference r3 after the immutable references causes a compile-time error because Rust cannot ensure that the data is not being read while it's being modified.

Lifetimes

Lifetimes in Rust are another crucial aspect of borrowing. They describe how long references are valid. Here's an example with explicit lifetimes:

Rust
1fn main() {
2 let string1 = String::from("abcd");
3 let string2 = "xyz";
4
5 let result = longest(string1.as_str(), string2);
6 println!("The longest string is {}", result);
7}
8
9fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
10 if x.len() > y.len() {
11 x
12 } else {
13 y
14 }
15}

In this example:

  • The function longest takes two string slices with the same lifetime 'a.
  • It returns a reference to one of the input strings, ensuring that the returned reference is valid as long as both input references are valid.

What's Next?

Now that you understand borrowing rules and lifetimes in Rust, you can explore more advanced topics such as trait objects, closures, and async programming. For further reading:

  • The Rust Programming Language Book
  • Rust by Example

These resources will provide deeper insights into Rust's ownership model and help you write safer and more efficient code.


PreviousOwnershipNext References

Recommended Gear

OwnershipReferences