rustbook_learning_guide/
ownership_borrowing.rs

1//! # Ownership and Borrowing
2//! 
3//! This module demonstrates Rust's ownership system, borrowing rules, and memory management.
4//! Understanding these concepts is crucial for writing safe and efficient Rust code.
5
6/// Demonstrates basic ownership concepts
7pub fn ownership_examples() {
8    println!("\nšŸ”’ Ownership Examples");
9    println!("{}", "-".repeat(20));
10    
11    // Basic ownership
12    let s1 = String::from("hello");
13    let s2 = s1; // s1 is moved to s2
14    // println!("{}", s1); // This would cause a compile error
15    println!("s2: {}", s2);
16    
17    // Clone to avoid move
18    let s3 = String::from("world");
19    let s4 = s3.clone();
20    println!("s3: {}, s4: {}", s3, s4);
21    
22    // Function ownership
23    let s = String::from("hello");
24    takes_ownership(s);
25    // println!("{}", s); // This would cause a compile error
26    
27    let x = 5;
28    makes_copy(x);
29    println!("x is still valid: {}", x); // This works because i32 implements Copy
30}
31
32fn takes_ownership(some_string: String) {
33    println!("Taking ownership of: {}", some_string);
34} // some_string goes out of scope and is dropped
35
36fn makes_copy(some_integer: i32) {
37    println!("Making copy of: {}", some_integer);
38} // some_integer goes out of scope, but nothing special happens
39
40/// Demonstrates borrowing and references
41pub fn borrowing_examples() {
42    println!("\nšŸ“š Borrowing Examples");
43    println!("{}", "-".repeat(20));
44    
45    let s1 = String::from("hello");
46    let len = calculate_length(&s1);
47    println!("The length of '{}' is {}.", s1, len);
48    
49    // Mutable references
50    let mut s = String::from("hello");
51    change(&mut s);
52    println!("Changed string: {}", s);
53    
54    // Multiple immutable references are allowed
55    let r1 = &s;
56    let r2 = &s;
57    println!("r1: {}, r2: {}", r1, r2);
58    
59    // But only one mutable reference at a time
60    let r3 = &mut s;
61    println!("r3: {}", r3);
62}
63
64fn calculate_length(s: &String) -> usize {
65    s.len()
66} // s goes out of scope, but because it doesn't have ownership, nothing happens
67
68fn change(some_string: &mut String) {
69    some_string.push_str(", world");
70}
71
72pub fn slice_examples() {
73    println!("\nšŸ° Slice Examples");
74    println!("{}", "-".repeat(20));
75    
76    let s = String::from("hello world");
77    
78    // String slices
79    let hello = &s[0..5];
80    let world = &s[6..11];
81    let whole = &s[..]; // Entire string
82    
83    println!("hello: {}, world: {}, whole: {}", hello, world, whole);
84    
85    // Array slices
86    let a = [1, 2, 3, 4, 5];
87    let slice = &a[1..3];
88    println!("Array slice: {:?}", slice);
89    
90    // First word function
91    let word = first_word(&s);
92    println!("First word: {}", word);
93}
94
95fn first_word(s: &str) -> &str {
96    let bytes = s.as_bytes();
97    
98    for (i, &item) in bytes.iter().enumerate() {
99        if item == b' ' {
100            return &s[0..i];
101        }
102    }
103    
104    &s[..]
105}
106
107
108
109
110
111
112
113