DEV Community

Subesh Yadav
Subesh Yadav

Posted on

🦀 Day 5 of #100DaysOfRust: Ownership Recap & Structs in Rust

Today was a big milestone in my Rust journey. I spent the day reviewing the foundational ownership system and then moved into one of Rust’s most powerful features—structs. Below is a detailed recap and breakdown of everything I learned, along with practical examples.

🔁 Ownership Recap

Rust’s ownership model ensures memory safety without a garbage collector. Let’s look at how it compares to garbage collection and revisit key ownership principles.

🔍 Ownership vs Garbage Collection

Languages like Python and Java use garbage collection (GC), where memory is freed by a background process. In contrast, Rust deallocates memory predictably at compile time through ownership and borrowing.

In Rust, each piece of heap data must have a single owner. When the owner goes out of scope, the memory is freed.

This eliminates GC pauses and unexpected mutations like in this Python example:

d = Document(words)
d2 = Document(d.get_words())
d2.add_word("world")
# This also mutates `d` unintentionally.
Enter fullscreen mode Exit fullscreen mode

Rust avoids this by requiring explicit references and ownership transfer.

🧠 Ownership: How Rust Thinks

🗃️ Stack vs Heap

Stack: Stores fixed-size data like numbers and pointers.

Heap: Stores growable data like String and Vec.

Example:

let a_box = Box::new(42);
let ref_stack = &a_box;       // Points to stack
let ref_heap = &*a_box;       // Points to heap
Enter fullscreen mode Exit fullscreen mode

🧾 Slices

A slice like &s[0..3] lets you reference part of a collection without taking ownership. These are “fat pointers” (contain length + pointer).

🧮 Ownership at Compile-Time

Rust uses permissions:

  • R (read)
  • W (write)
  • O (own)

Example of move (loses ownership):

let s = String::from("hello");
let s2 = s;     // Ownership moved to s2
println!("{}", s); // ❌ Error: s no longer valid
Enter fullscreen mode Exit fullscreen mode

📌 Borrowing

Immutable reference (&T) removes write/own from original.

Mutable reference (&mut T) removes all access from the original.

✅ Valid:

let mut s = String::from("Hello");
let r = &s; // read-only
println!("{}", r);
Enter fullscreen mode Exit fullscreen mode

❌ Invalid:

let r1 = &mut s;
let r2 = &s;     // ❌ Can't borrow as immutable while mutably borrowed
Enter fullscreen mode Exit fullscreen mode

🧨 Use-after-free & Double Free

Rust prevents undefined behavior like:

Using a pointer after its memory is freed

Freeing memory twice

📦 Structs: Custom Data Types

Coming from JavaScript, I’m very familiar with objects — key-value pairs like:

const user = {
  username: "subesh",
  email: "me@mail.com",
  active: true
};
Enter fullscreen mode Exit fullscreen mode

In Rust, structs serve a similar purpose. They let you group related data under a single type, but in a strongly typed, memory-safe way.

✅ Basic Struct Definition

This is how you define a struct in Rust:

struct User {
    username: String,
    email: String,
    active: bool,
    sign_in_count: u64,
}
Enter fullscreen mode Exit fullscreen mode

It’s like a typed version of a JS object, where each field has a clear type.

🛠 Creating Instances

You can now create values of the User type:

let user1 = User {
    username: String::from("user1"),
    email: String::from("test@testmail.com"),
    active: true,
    sign_in_count: 1,
};
Enter fullscreen mode Exit fullscreen mode

Rust enforces ownership here too — values like String are moved into the struct unless cloned.

🧾 Field Access & Mutation

You can read fields using dot notation, and update them if the struct is mutable:

println!("{}", user1.email);

let mut user2 = user1;
user2.email = String::from("new@mail.com");
Enter fullscreen mode Exit fullscreen mode

This is very JS-like in syntax but with the added safety of the compiler checking types and ownership.

✨ Struct Update Syntax

You can also create new structs by reusing existing ones:

let user2 = User {
    username: String::from("newuser"),
    ..user1
};
Enter fullscreen mode Exit fullscreen mode

Rust will move the values that aren't copied (like String), so user1 becomes partially invalid after this unless its fields are Copy.

🪄 Tuple Structs

Tuple structs look like this:

struct Color(i32, i32, i32);
let black = Color(0, 0, 0);
println!("{}", black.0);
Enter fullscreen mode Exit fullscreen mode

They’re great when the meaning is clear by position — similar to using arrays in JS for unnamed data.

💠 Unit-like Structs

These are structs without fields. They’re useful when you just want to implement traits or act as markers:

struct AlwaysEqual;
let a = AlwaysEqual;
Enter fullscreen mode Exit fullscreen mode

🔐 Field Ownership in Structs

This is where Rust differs from JS. In JavaScript, fields can be strings, numbers, or even references to other objects without worrying about ownership. In Rust, each field needs to either own its data or borrow it with a lifetime.

Prefer using String in structs:

struct User {
    username: String,
}
Enter fullscreen mode Exit fullscreen mode

Over this:

struct User {
    username: &str, // ❌ Needs lifetime annotation
}
Enter fullscreen mode Exit fullscreen mode

🕹 Borrowing Fields

Rust lets you borrow individual fields, but prevents simultaneous conflicting borrows:

struct Point { x: i32, y: i32 }

let mut p = Point { x: 1, y: 2 };
let x = &mut p.x;
// Can't use p.y while x is borrowed mutably
Enter fullscreen mode Exit fullscreen mode

This might feel restrictive coming from JS, but it avoids hard-to-debug bugs.

📝 Summary

  • Rust avoids garbage collection using ownership.
  • Borrowing rules (with permissions R, W, O) ensure memory safety.
  • Structs in Rust are like strongly-typed JS objects, but safer.
  • You can define named structs, tuple structs, and unit structs.
  • Borrowing and mutating fields inside structs follows strict rules.
  • Prefer owned types like String over borrowed ones unless using lifetimes explicitly.

That’s all for Day 5. Tomorrow, I’ll dive into methods and enums—building more expressive and safe Rust programs.

Let me know what you're learning too! 🚀

Follow my journey on Twitter @subeshyadav

rustlang #100DaysOfRust #buildinpublic #learninpublic #100DaysOfCode

Top comments (0)