References and Slices
# CHAPTER 11
References and Slices
1. Chapter Introduction
In Chapter 10, we learned that passing aString into a function transfers ownership, destroying our access to it in the original function. This is highly inconvenient. What if we just want the function to *look* at the data? In Rust, we use References. This act is called Borrowing. We will also explore Slices, which allow us to reference a specific portion of a collection.
2. Learning Objectives
By the end of this chapter, you will be able to:-
Use the
&operator to create a reference.
- Pass parameters by reference to avoid moving ownership.
-
Create mutable references using
&mut.
- Understand the strict rules of the Borrow Checker.
-
Extract partial data using String Slices (
&str).
3. Borrowing (Immutable References)
A Reference allows you to refer to some value without taking ownership of it. You create a reference using the ampersand symbol:&.
4. Mutable References
Just like variables are immutable by default, references are immutable by default. You cannot modify borrowed data!To modify borrowed data, you must:
-
1.
Make the original variable mutable (
let mut s).
-
2.
Pass a mutable reference (
&mut s).
-
3.
Accept a mutable reference in the function signature (
s: &mut String).
5. The Rules of the Borrow Checker (CRITICAL)
Rust allows you to borrow data, but the Borrow Checker strictly enforces two rules to prevent Data Races (where two threads try to modify data simultaneously, causing corruption):Rule 1: You can have EITHER one mutable reference, OR any number of immutable references at the exact same time. Never both.
Rule 2: References must always be valid (No Dangling Pointers). You cannot return a reference to a variable created inside a function, because that variable is deleted when the function ends!
6. The Slice Type (&str)
A Slice is a special kind of reference. Instead of referencing the entire collection, it references a *contiguous sequence* of elements. Slices do not have ownership.
String slices are written as &str.
*Note: String literals (e.g., let word = "Rust";) are actually String slices (&str) pointing directly to the compiled binary memory.*
7. Mini Project: First Word Finder
Let's write a function that finds the first word in a sentence and returns a slice of it.8. Common Mistakes
-
Mixing
&and&mut: Trying to read data via an immutable reference while a mutable reference is actively changing it. The compiler will block this to prevent race conditions.
- Dangling References: Attempting to return a pointer/reference to a local variable that dies at the end of the function.
9. Best Practices
-
Prefer
&stras parameters: If you are writing a function that only needs to read a string, don't usefn myfunc(s: &String). Usefn myfunc(s: &str). This makes your API much more flexible, as it can accept bothStringreferences and raw string literals!
10. Exercises
-
1.
Create a mutable string
greetingcontaining "Good".
-
2.
Create a function
add_morningthat accepts a mutable reference to a string and appends " Morning" to it.
-
3.
Call it in
mainand print the mutated string.
11. MCQs with Answers
What symbol is used to create a reference (borrow) in Rust?
Q2. When you pass data by reference (&x), does ownership transfer?
a) Yes b) No, the original function retains ownership
Answer: b) No.
Q3. Are references mutable by default? a) Yes b) No Answer: b) No.
What syntax is used to create a mutable reference?
According to the Borrow Checker, how many mutable references to a single piece of data can exist at the exact same time in the same scope?
What is a "Dangling Reference"?
What does &s[0..5] create?
What data type is a String Literal (e.g., "Hello")?
Why does Rust enforce these strict borrowing rules?
12. Interview Questions
- Q: State the two primary rules of References and Borrowing in Rust.
- Q: Why does Rust prevent having an immutable reference and a mutable reference to the same data active at the same time? (Answer: Because the immutable reference expects the data to remain constant. If the mutable reference changes it underneath, the immutable reference reads corrupted data—a classic race condition).