<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Maksim Gritchin</title>
    <description>The latest articles on Forem by Maksim Gritchin (@gritmax).</description>
    <link>https://forem.com/gritmax</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1036451%2Ff7771c57-eaf8-48ab-a6da-7927ac89479b.jpg</url>
      <title>Forem: Maksim Gritchin</title>
      <link>https://forem.com/gritmax</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/gritmax"/>
    <language>en</language>
    <item>
      <title>Memory Allocations in Rust</title>
      <dc:creator>Maksim Gritchin</dc:creator>
      <pubDate>Tue, 25 Jun 2024 21:24:39 +0000</pubDate>
      <link>https://forem.com/gritmax/memory-allocations-in-rust-3m7l</link>
      <guid>https://forem.com/gritmax/memory-allocations-in-rust-3m7l</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Welcome to this in-depth tutorial on memory allocations in Rust. As a developer, understanding how Rust manages memory is crucial for writing efficient and safe programs. This guide is the result of analysing several expert sources to provide you with a comprehensive overview of memory management, not just in Rust, but in programming languages in general.&lt;/p&gt;

&lt;p&gt;It's important to note that some concepts discussed here can be quite complex and may require further research on your part to fully grasp. Don't be discouraged if you find certain topics challenging – memory management is a deep subject, and even experienced developers continually learn new aspects of it.&lt;/p&gt;

&lt;p&gt;We'll start with basic concepts that apply to many programming languages and then focus on Rust-specific implementations. By the end of this tutorial, you'll have a solid foundation in Rust's memory allocation strategies and how to implement them effectively in your projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Memory Layout Basics
&lt;/h2&gt;

&lt;p&gt;Before we delve into Rust-specific concepts, it's essential to understand the basic memory layout of a program.&lt;/p&gt;

&lt;h3&gt;
  
  
  Executable Binary Structure
&lt;/h3&gt;

&lt;p&gt;When you compile a Rust program, the result is an executable binary. The operating system kernel provides a continuous range of virtual memory addresses mapped to physical memory addresses for your program to use.&lt;/p&gt;

&lt;h4&gt;
  
  
  ELF Executable Structure
&lt;/h4&gt;

&lt;p&gt;When discussing the structure of executables, it's crucial to distinguish between the file format on disk and the memory layout during runtime. Let's focus on the Executable and Linkable Format (ELF), commonly used in Linux systems.&lt;/p&gt;

&lt;h4&gt;
  
  
  ELF File Structure
&lt;/h4&gt;

&lt;p&gt;An ELF file consists of several parts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;ELF Header&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Contains metadata about the file type, target architecture, entry point, etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Program Header Table&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Describes how to create a process/memory image for runtime execution.&lt;/li&gt;
&lt;li&gt;Defines segments for the loader.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Section Header Table&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Describes the sections of the file in detail.&lt;/li&gt;
&lt;li&gt;More relevant for linking and debugging.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sections&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Contain the actual data and code. Common sections include:

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;.text&lt;/code&gt;: Executable code&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.data&lt;/code&gt;: Initialized data&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.rodata&lt;/code&gt;: Read-only data&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.bss&lt;/code&gt;: Uninitialized data (doesn't actually take space in the file)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Key Points
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Sections vs Segments&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Sections are used by the linker and for debugging.&lt;/li&gt;
&lt;li&gt;Segments are used by the loader to create the process image.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Read-Only Nature&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;The executable file itself is typically read-only.&lt;/li&gt;
&lt;li&gt;Writable sections are loaded into writable memory at runtime.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Runtime vs File Structure&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;The file structure (sections) differs from the runtime memory layout.&lt;/li&gt;
&lt;li&gt;The loader uses the program header to set up the runtime memory.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Runtime Memory Layout
&lt;/h4&gt;

&lt;p&gt;When the program is loaded:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The loader reads the program header.&lt;/li&gt;
&lt;li&gt;It sets up the process memory according to the defined segments.&lt;/li&gt;
&lt;li&gt;This includes setting up the stack and initialising the heap.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It's important to note that stack and heap are runtime concepts and are not present in the executable file itself. They are allocated and managed by the operating system when the program runs. More read &lt;a href="https://oswalt.dev/2020/11/anatomy-of-a-binary-executable/"&gt;Binary Executable&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Stack vs Heap
&lt;/h2&gt;

&lt;p&gt;Now, let's focus on the two primary types of memory allocation in Rust: stack and heap.&lt;/p&gt;

&lt;h3&gt;
  
  
  Stack
&lt;/h3&gt;

&lt;p&gt;The stack is a region of memory that follows a Last-In-First-Out (LIFO) order. It's used for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Local variables&lt;/li&gt;
&lt;li&gt;Function parameters&lt;/li&gt;
&lt;li&gt;Return addresses&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Key characteristics of stack allocation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fast allocation and deallocation&lt;/li&gt;
&lt;li&gt;Limited in size (typically 8MB on 64-bit Linux systems for the main thread, 2MB for other threads)&lt;/li&gt;
&lt;li&gt;Non-fragmented&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Heap
&lt;/h3&gt;

&lt;p&gt;The heap is a region of memory used for dynamic allocation. It's managed by Rust's global allocator trait, which often uses the C library's malloc under the hood. Key characteristics include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Flexible size&lt;/li&gt;
&lt;li&gt;Slower allocation and deallocation compared to the stack&lt;/li&gt;
&lt;li&gt;Can lead to fragmentation&lt;/li&gt;
&lt;li&gt;Shared among all threads&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Function Stack Frames
&lt;/h3&gt;

&lt;p&gt;When a function is called, a new stack frame is created. This frame stores:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Function parameters&lt;/li&gt;
&lt;li&gt;Local variables&lt;/li&gt;
&lt;li&gt;Return address&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The stack pointer keeps track of the top of the stack, changing as functions are called and return.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rust's Approach to Memory Management
&lt;/h2&gt;

&lt;p&gt;Rust's memory management is built on two key concepts: ownership and borrowing. These rules allow Rust to manage memory without a garbage collector, ensuring memory safety and preventing common issues like null or dangling pointers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ownership Rules
&lt;/h3&gt;

&lt;h4&gt;
  
  
  General Ownership Rules
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Single Owner Principle&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;At any given time, a value in memory is typically owned by a single binding.&lt;/li&gt;
&lt;li&gt;When an owner goes out of scope, Rust automatically deallocates the value.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Move Semantics&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Assigning a value to another variable typically moves ownership.&lt;/li&gt;
&lt;li&gt;After a move, the original binding can no longer be used.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Borrowing&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Values can be borrowed without transferring ownership.&lt;/li&gt;
&lt;li&gt;Multiple immutable borrows or one mutable borrow are allowed at a time.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let's look at an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;s1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"hello"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;s2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// ownership of the string moves to s2&lt;/span&gt;

    &lt;span class="c1"&gt;// println!("{}", s1);  // This would cause a compile-time error&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;s2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// This is fine&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, &lt;code&gt;s1&lt;/code&gt; initially owns the String. When we assign &lt;code&gt;s1&lt;/code&gt; to &lt;code&gt;s2&lt;/code&gt;, the ownership is moved, and &lt;code&gt;s1&lt;/code&gt; is no longer valid.&lt;/p&gt;

&lt;h4&gt;
  
  
  Exceptions and Special Cases
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Constants&lt;/strong&gt;:
&lt;code&gt;const N: u32 = 5;&lt;/code&gt;
Constants do not have an owner in the traditional sense. They are compile-time constructs, inlined where used.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Statics&lt;/strong&gt;:
&lt;code&gt;static N: u32 = 5;&lt;/code&gt;
Static items have a fixed memory address for the entire program runtime. They are not owned by any particular part of the code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;References to Compile-Time Constants&lt;/strong&gt;:
&lt;code&gt;let r = &amp;amp;42;&lt;/code&gt;
These do not follow standard ownership rules.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Temporary Values&lt;/strong&gt;:
&lt;code&gt;println!("{}", String::from("hello"));&lt;/code&gt;
Created and destroyed within the expression. Not bound to any variable or subject to normal ownership rules.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Primitive Types&lt;/strong&gt;:
Types that implement the &lt;code&gt;Copy&lt;/code&gt; trait (like integers, booleans) are copied rather than moved.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Borrowing
&lt;/h3&gt;

&lt;p&gt;Borrowing allows you to refer to a value without taking ownership. There are two types of borrows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Read-only borrows&lt;/strong&gt;: Multiple read-only borrows are allowed simultaneously.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mutable borrows&lt;/strong&gt;: Only one mutable borrow is allowed at a time.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here's an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"hello"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;r1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// read-only borrow&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;r2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// another read-only borrow&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{} and {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;r3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// mutable borrow&lt;/span&gt;
    &lt;span class="n"&gt;r3&lt;/span&gt;&lt;span class="nf"&gt;.push_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;", world"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This borrowing system allows Rust to prevent data races at compile-time, a significant advantage over many other programming languages.&lt;/p&gt;

&lt;h2&gt;
  
  
  Data Types and Memory Allocation
&lt;/h2&gt;

&lt;p&gt;Understanding how different data types are allocated in memory is crucial for writing efficient Rust code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Primitive Data Types
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Categories of Primitive Types
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Scalar Types&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Integers: &lt;code&gt;i8&lt;/code&gt;, &lt;code&gt;i16&lt;/code&gt;, &lt;code&gt;i32&lt;/code&gt;, &lt;code&gt;i64&lt;/code&gt;, &lt;code&gt;i128&lt;/code&gt;, &lt;code&gt;isize&lt;/code&gt;, &lt;code&gt;u8&lt;/code&gt;, &lt;code&gt;u16&lt;/code&gt;, &lt;code&gt;u32&lt;/code&gt;, &lt;code&gt;u64&lt;/code&gt;, &lt;code&gt;u128&lt;/code&gt;, &lt;code&gt;usize&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Floating-point: &lt;code&gt;f32&lt;/code&gt;, &lt;code&gt;f64&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Boolean: &lt;code&gt;bool&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Character: &lt;code&gt;char&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compound Types&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Arrays: &lt;code&gt;[T; N]&lt;/code&gt; where &lt;code&gt;T&lt;/code&gt; is any type and &lt;code&gt;N&lt;/code&gt; is a compile-time constant&lt;/li&gt;
&lt;li&gt;Slices: &lt;code&gt;&amp;amp;[T]&lt;/code&gt; and &lt;code&gt;&amp;amp;mut [T]&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Tuples: &lt;code&gt;(T, U, ...)&lt;/code&gt; where &lt;code&gt;T&lt;/code&gt;, &lt;code&gt;U&lt;/code&gt;, etc. can be any types&lt;/li&gt;
&lt;li&gt;String slices: &lt;code&gt;&amp;amp;str&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pointer Types&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;References: &lt;code&gt;&amp;amp;T&lt;/code&gt; and &lt;code&gt;&amp;amp;mut T&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Raw pointers: &lt;code&gt;*const T&lt;/code&gt; and &lt;code&gt;*mut T&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Function pointers: &lt;code&gt;fn()&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  The &lt;code&gt;Copy&lt;/code&gt; Trait
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Primitive  types above implement the &lt;code&gt;Copy&lt;/code&gt; trait.&lt;/li&gt;
&lt;li&gt;Arrays &lt;code&gt;[T; N]&lt;/code&gt; implement &lt;code&gt;Copy&lt;/code&gt; if &lt;code&gt;T&lt;/code&gt; implements &lt;code&gt;Copy&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Slices &lt;code&gt;&amp;amp;[T]&lt;/code&gt;, references &lt;code&gt;&amp;amp;T&lt;/code&gt;, and string slices &lt;code&gt;&amp;amp;str&lt;/code&gt; always implement &lt;code&gt;Copy&lt;/code&gt;, regardless of &lt;code&gt;T&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Storage Location
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Primitive types can be stored on either the stack or the heap.&lt;/li&gt;
&lt;li&gt;Non-primitive types can also be stored on either the stack or the heap.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Primitive type on the heap&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;boxed_int&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Box&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Box&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Array (primitive) on the heap&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;boxed_array&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Box&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Box&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="c1"&gt;// Non-primitive type on the stack&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Point&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Point&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;  &lt;span class="c1"&gt;// Stored on the stack&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Memory Layout
&lt;/h4&gt;

&lt;p&gt;Primitive types typically have a fixed, known size at compile-time. This allows for efficient stack allocation and direct manipulation. However, this doesn't mean they're always stack-allocated. The context of use determines the actual storage location. Some scenarios where a typically stack-allocated value might end up on the heap include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When it's part of a larger data structure that's heap-allocated. For example, if a primitive type is stored in a Vec or Box, it will be on the heap along with the rest of the data structure.&lt;/li&gt;
&lt;li&gt;When it's used in a closure that outlives the current stack frame.&lt;/li&gt;
&lt;li&gt;When it's returned from a function as part of a heap-allocated structure.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Compound Data Types
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Array
&lt;/h4&gt;

&lt;p&gt;Arrays in Rust have a fixed size known at compile time and are stored on the stack. This is different from some popular languages like Python or JavaScript, where arrays (or lists) are dynamically sized and heap-allocated. In Rust:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This array is entirely stack-allocated, which can lead to very efficient memory use and access patterns for fixed-size collections.&lt;/p&gt;

&lt;h4&gt;
  
  
  Tuples
&lt;/h4&gt;

&lt;p&gt;Tuples store values of different types and are allocated on the stack. They're laid out in memory contiguously, with potential padding for alignment. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;tup&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;6.4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In memory, this tuple might look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="n"&gt;bytes&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="n"&gt;bytes&lt;/span&gt; &lt;span class="n"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="n"&gt;bytes&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;byte&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt; &lt;span class="n"&gt;bytes&lt;/span&gt; &lt;span class="n"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The padding ensures that each element is properly aligned in memory.&lt;/p&gt;

&lt;h4&gt;
  
  
  Structs
&lt;/h4&gt;

&lt;p&gt;Structs can be named or tuple-like. They are typically allocated on the stack, but their contents can be on the heap if they contain types like &lt;code&gt;String&lt;/code&gt; or &lt;code&gt;Vec&lt;/code&gt;. Their memory layout is similar to tuples, including potential padding. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Point&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Point&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Enums
&lt;/h4&gt;

&lt;p&gt;Enums are stored as a discriminant (usually an integer) to indicate which variant it is, plus enough space to store the largest variant. This allows Rust to optimise memory usage while providing type safety. The memory allocation can be more complex than it first appears:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;Message&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Quit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Move&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nf"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nf"&gt;ChangeColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this enum:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Quit&lt;/code&gt; doesn't need any extra space beyond the discriminant.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Move&lt;/code&gt; needs space for two &lt;code&gt;i32&lt;/code&gt; values.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Write&lt;/code&gt; needs space for a &lt;code&gt;String&lt;/code&gt;, which is a pointer to heap memory.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ChangeColor&lt;/code&gt; needs space for three &lt;code&gt;i32&lt;/code&gt; values.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The enum will allocate enough space for the largest variant (likely &lt;code&gt;ChangeColor&lt;/code&gt; in this case), plus the discriminant. This means even the &lt;code&gt;Quit&lt;/code&gt; variant will use the same amount of memory as &lt;code&gt;ChangeColor&lt;/code&gt;, but this approach allows for very fast matching and prevents the need for heap allocations for the enum itself.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dynamic Data Types
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Vector
&lt;/h4&gt;

&lt;p&gt;Vectors are resizable and store their data on the heap. They keep track of capacity and length:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;vec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Vec&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;vec&lt;/span&gt;&lt;span class="nf"&gt;.push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;vec&lt;/span&gt;&lt;span class="nf"&gt;.push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Slice
&lt;/h4&gt;

&lt;p&gt;Slices are views into elements of an array or vector. They use a fat pointer for reference, containing both a pointer to the data and the length. A fat pointer is a pointer that carries additional information beyond just the memory address. In the case of a slice, the fat pointer contains:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A pointer to the first element of the slice in memory&lt;/li&gt;
&lt;li&gt;The length of the slice&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This additional information allows Rust to perform bounds checking and iterate over the slice efficiently without needing to store this information separately or query it at runtime.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  String
&lt;/h4&gt;

&lt;p&gt;Strings in Rust are similar to vectors but are guaranteed to be UTF-8 encoded. This guarantee means:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Each character in the string is represented by a valid UTF-8 byte sequence.&lt;/li&gt;
&lt;li&gt;The string can contain any Unicode character, but they're stored efficiently.&lt;/li&gt;
&lt;li&gt;String operations (like indexing) work on UTF-8 boundaries, not raw bytes.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This UTF-8 guarantee allows Rust to provide safe and efficient string handling, avoiding issues like invalid byte sequences or incorrect character boundaries that can occur in languages with less strict string encodings.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"hello"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Stack Allocation in Rust
&lt;/h3&gt;

&lt;p&gt;In Rust, stack allocation is not limited to primitive types or small objects. Rust allows for stack allocation of objects of arbitrary complexity and size, subject only to the stack size limit. This is indeed different from many other programming languages and is an important feature of Rust's memory model. More read &lt;a href="https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html#the-stack-and-the-heap"&gt;Stack and Heap&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Key Points:
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Arbitrary Complexity&lt;/strong&gt;: In Rust, you can allocate structs, enums, arrays, and other complex types on the stack, not just primitives.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Size Flexibility&lt;/strong&gt;: As long as the size is known at compile time and doesn't exceed the stack limit, you can allocate large objects on the stack.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance Implications&lt;/strong&gt;: Stack allocation is generally faster than heap allocation, so this feature can lead to performance benefits.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stack Size Limit&lt;/strong&gt;: While you can allocate complex objects on the stack, you still need to be aware of the stack size limit, which is typically much smaller than the heap.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Memory Allocators in Rust
&lt;/h2&gt;

&lt;p&gt;Rust provides flexibility in choosing memory allocators. Let's explore some common options:&lt;/p&gt;

&lt;h3&gt;
  
  
  Standard Allocator
&lt;/h3&gt;

&lt;p&gt;The standard allocator in Rust uses the system's default allocator (often the C library's &lt;code&gt;malloc&lt;/code&gt;). It's a good general-purpose allocator but may not be the most efficient for all scenarios.&lt;/p&gt;

&lt;p&gt;Characteristics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Uses &lt;code&gt;sbrk&lt;/code&gt; to grow the heap&lt;/li&gt;
&lt;li&gt;Memory is counted towards Resident Set Size (RSS)&lt;/li&gt;
&lt;li&gt;Not the fastest or most memory-efficient&lt;/li&gt;
&lt;li&gt;Low memory footprint upon initialization&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  jemalloc
&lt;/h3&gt;

&lt;p&gt;jemalloc is a popular alternative allocator known for its efficiency in multi-threaded environments.&lt;/p&gt;

&lt;p&gt;Characteristics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Uses &lt;code&gt;mmap&lt;/code&gt; to allocate memory&lt;/li&gt;
&lt;li&gt;Memory only counts towards RSS when written to&lt;/li&gt;
&lt;li&gt;Efficient in managing "dirty" pages (memory freed but not returned to OS)&lt;/li&gt;
&lt;li&gt;High initial memory footprint&lt;/li&gt;
&lt;li&gt;Can be tuned for performance or memory efficiency for heavy workloads&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To use jemalloc in your Rust project:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Add it to your &lt;code&gt;Cargo.toml&lt;/code&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;   &lt;span class="nn"&gt;[dependencies]&lt;/span&gt;
   &lt;span class="py"&gt;jemallocator&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"0.3.2"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Set it as the global allocator in your main Rust file:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;   &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;jemallocator&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Jemalloc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

   &lt;span class="nd"&gt;#[global_allocator]&lt;/span&gt;
   &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;GLOBAL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Jemalloc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Jemalloc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Microsoft's mimalloc
&lt;/h3&gt;

&lt;p&gt;mimalloc is another high-performance allocator known for its speed and low initial memory footprint.&lt;/p&gt;

&lt;p&gt;Characteristics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Very fast&lt;/li&gt;
&lt;li&gt;Low initial memory footprint&lt;/li&gt;
&lt;li&gt;Good choice for applications that require quick startup times&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Advanced Memory Management Techniques
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Using &lt;code&gt;Box&amp;lt;T&amp;gt;&lt;/code&gt; for Heap Allocation
&lt;/h3&gt;

&lt;p&gt;When you need to allocate memory on the heap explicitly, Rust provides the &lt;code&gt;Box&amp;lt;T&amp;gt;&lt;/code&gt; type. This is useful for recursive data structures or when you need to ensure a value has a stable memory address.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Box&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"b = {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When &lt;code&gt;b&lt;/code&gt; goes out of scope, the heap memory is automatically deallocated.&lt;/p&gt;

&lt;h3&gt;
  
  
  Reference Counting with &lt;code&gt;Rc&amp;lt;T&amp;gt;&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;For scenarios where you need shared ownership of data (e.g., in graph-like structures), Rust provides &lt;code&gt;Rc&amp;lt;T&amp;gt;&lt;/code&gt; (Reference Counted).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;rc&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;Rc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Rc&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;  &lt;span class="c1"&gt;// Increases the reference count&lt;/span&gt;

    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"a: {}, b: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Rc&amp;lt;T&amp;gt;&lt;/code&gt; keeps track of the number of references to a value and only deallocates the value when the reference count reaches zero.&lt;/p&gt;

&lt;h3&gt;
  
  
  Atomic Reference Counting with &lt;code&gt;Arc&amp;lt;T&amp;gt;&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;For thread-safe reference counting, Rust provides &lt;code&gt;Arc&amp;lt;T&amp;gt;&lt;/code&gt; (Atomic Reference Counted). It's similar to &lt;code&gt;Rc&amp;lt;T&amp;gt;&lt;/code&gt; but safe to use across multiple threads.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;sync&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;Arc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;thread&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Arc&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"shared data"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Arc&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;clone&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nn"&gt;thread&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;spawn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;move&lt;/span&gt; &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Optimising Memory Usage
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Struct Layout
&lt;/h3&gt;

&lt;p&gt;Rust allows you to optimise memory usage by considering struct layout. Let's look at an example and explain the paddings:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Efficient&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Inefficient&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the &lt;code&gt;Efficient&lt;/code&gt; struct:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;a&lt;/code&gt; occupies 4 bytes&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;b&lt;/code&gt; occupies the next 4 bytes&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;c&lt;/code&gt; occupies the next 2 bytes&lt;/li&gt;
&lt;li&gt;Total: 10 bytes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the &lt;code&gt;Inefficient&lt;/code&gt; struct:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;a&lt;/code&gt; occupies 4 bytes&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;c&lt;/code&gt; occupies the next 2 bytes&lt;/li&gt;
&lt;li&gt;2 bytes of padding are added to align &lt;code&gt;b&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;b&lt;/code&gt; occupies the next 4 bytes&lt;/li&gt;
&lt;li&gt;Total: 12 bytes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code&gt;Efficient&lt;/code&gt; struct uses less memory due to better alignment and less padding. The compiler adds padding to ensure that each field is aligned to its natural alignment (usually its size). By ordering fields from largest to smallest, we can often reduce the amount of padding needed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Copy vs Clone
&lt;/h3&gt;

&lt;p&gt;Understanding the difference between &lt;code&gt;Copy&lt;/code&gt; and &lt;code&gt;Clone&lt;/code&gt; traits can help you optimise memory usage:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Copy&lt;/code&gt;: Allows bitwise copying of values. Use for small, stack-allocated types.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Clone&lt;/code&gt;: Allows more complex copying logic. Use for heap-allocated or larger types.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[derive(Copy,&lt;/span&gt; &lt;span class="nd"&gt;Clone)]&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Point&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;#[derive(Clone)]&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;ComplexData&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Option Type Optimization
&lt;/h3&gt;

&lt;p&gt;Rust's &lt;code&gt;Option&lt;/code&gt; type is optimized to avoid null pointers. For types that cannot be null (like &lt;code&gt;Box&amp;lt;T&amp;gt;&lt;/code&gt;), Rust uses a clever optimization where the &lt;code&gt;None&lt;/code&gt; variant doesn't take up any extra space.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="nb"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nb"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;Box&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;None&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case, &lt;code&gt;x&lt;/code&gt; doesn't allocate any heap memory.&lt;/p&gt;

&lt;h2&gt;
  
  
  Advanced Concepts
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Memory Pages and Virtual Memory
&lt;/h3&gt;

&lt;p&gt;Understanding how the operating system manages memory can help you write more efficient Rust code. The OS allocates memory in pages (usually 4096 bytes). When your program requests memory, it's given in multiples of these pages.&lt;/p&gt;

&lt;p&gt;Virtual Memory allows your program to use more memory than is physically available. The OS maps virtual memory addresses to physical memory or disk storage.&lt;/p&gt;

&lt;h3&gt;
  
  
  Resident Set Size (RSS) vs Virtual Memory
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Virtual Memory&lt;/strong&gt;: The amount of memory your program can use.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RSS (Resident Set Size)&lt;/strong&gt;: The actual memory used by your program.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Different allocators manage these differently. For example, jemalloc uses &lt;code&gt;mmap&lt;/code&gt; to allocate memory, which only counts towards RSS when written to.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tuning jemalloc
&lt;/h3&gt;

&lt;p&gt;jemalloc offers various tuning options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Multiple arenas to limit fragmentation&lt;/li&gt;
&lt;li&gt;Background cleanup threads&lt;/li&gt;
&lt;li&gt;Profiling options to monitor memory usage&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These can be configured through environment variables or at runtime.&lt;/p&gt;

&lt;h2&gt;
  
  
  Best Practices for Memory Management in Rust
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Use stack allocation when possible&lt;/strong&gt;: Stack allocation is faster and doesn't require explicit deallocation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Leverage Rust's ownership system&lt;/strong&gt;: Let Rust's ownership and borrowing rules manage memory for you whenever possible.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Use appropriate data structures&lt;/strong&gt;: Choose data structures that match your access patterns and memory requirements.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Consider custom allocators for specific use cases&lt;/strong&gt;: If your application has unique memory requirements, consider implementing a custom allocator.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Profile your application&lt;/strong&gt;: Use tools like &lt;code&gt;valgrind&lt;/code&gt; or Rust-specific profilers to identify memory bottlenecks.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Avoid premature optimization&lt;/strong&gt;: Focus on writing clear, idiomatic Rust code first. Optimize only when necessary and after profiling.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Use &lt;code&gt;Box&amp;lt;T&amp;gt;&lt;/code&gt; for large objects or recursive data structures&lt;/strong&gt;: This moves data to the heap, which can be more efficient for large objects.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Be mindful of lifetimes&lt;/strong&gt;: Understand and use Rust's lifetime system to ensure references remain valid.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Utilize &lt;code&gt;Rc&amp;lt;T&amp;gt;&lt;/code&gt; and &lt;code&gt;Arc&amp;lt;T&amp;gt;&lt;/code&gt; judiciously&lt;/strong&gt;: These types are useful for shared ownership but come with a performance cost.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Consider using arena allocators for short-lived objects&lt;/strong&gt;: This can significantly reduce allocation overhead in some scenarios.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Memory management in Rust is a powerful feature that sets it apart from many other programming languages. By understanding and leveraging Rust's ownership model, borrowing rules, and allocation strategies, you can write efficient, safe, and performant code.&lt;/p&gt;

&lt;p&gt;Remember that mastering memory management in Rust is a journey. The concepts we've covered here provide a solid foundation, but there's always more to learn. Don't hesitate to dive deeper into Rust's documentation, experiment with different allocation strategies, and engage with the Rust community to further enhance your understanding.&lt;/p&gt;

&lt;p&gt;As you continue to work with Rust, you'll become more adept at managing memory efficiently. This will lead to robust, high-performance applications that are free from many common memory-related bugs.&lt;/p&gt;

&lt;p&gt;Keep practicing, keep learning, and embrace the challenges – they're opportunities for growth.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt; &lt;a href="https://youtu.be/5yy64sy2oSM?si=AkA2x-PTdfAwL3rV"&gt;Rainer Stropek - Memory Management in Rust&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/fpkjmE-56Gw?si=5JJhmfDgqx_fCuaR"&gt;Rust Allocators and Memory Management&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/rDoqT-a6UFg?si=Oyn0gy1nsbv6XSO_"&gt;Visualizing memory layout of Rust's data types&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>rust</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Rust Diagnostic Attributes</title>
      <dc:creator>Maksim Gritchin</dc:creator>
      <pubDate>Tue, 18 Jun 2024 20:53:11 +0000</pubDate>
      <link>https://forem.com/gritmax/rust-diagnostic-attributes-7kk</link>
      <guid>https://forem.com/gritmax/rust-diagnostic-attributes-7kk</guid>
      <description>&lt;p&gt;Rust has introduced a powerful feature known as diagnostic attributes, which allows me to customise the error messages emitted by the compiler. This feature is particularly useful for improving the clarity of error messages, especially in complex scenarios involving traits and type mismatches.&lt;/p&gt;

&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;The diagnostic attributes are part of a new built-in namespace, &lt;code&gt;#[diagnostic]&lt;/code&gt;, introduced in Rust 1.78. These attributes help provide more informative and context-specific error messages, making it easier for developers to understand and fix issues. Rust is known for its helpful error messages, but there are always cases where they can be improved. Crates that use the type system to verify invariants at compile time often generate large, unclear error messages when something goes wrong. Examples include Bevy, Axum, and Diesel. By giving crate authors tools to control the error messages emitted by the compiler, they can make these messages clearer and more helpful.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Features
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Custom Error Messages&lt;/strong&gt;: One of the main attributes in this namespace is &lt;code&gt;#[diagnostic::on_unimplemented]&lt;/code&gt;. This attribute allows trait authors to specify custom error messages when a trait is required but not implemented for a type. For example, instead of a generic error message, you can provide a detailed explanation and hints on how to resolve the issue.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Non-Intrusive&lt;/strong&gt;: The attributes in the &lt;code&gt;#[diagnostic]&lt;/code&gt; namespace are designed to be non-intrusive. They do not affect the compilation result and are purely for enhancing the diagnostic output. This means that applying these attributes will not cause compilation errors as long as they are syntactically valid.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Compiler Flexibility&lt;/strong&gt;: The compiler treats these diagnostic hints as optional. It may choose to ignore specific attributes or options, and the support for these attributes can change over time. However, the compiler must not change the semantics of an attribute or emit hard errors for malformed attributes.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Usage Example
&lt;/h2&gt;

&lt;p&gt;Here is an example of how to use the &lt;code&gt;#[diagnostic::on_unimplemented]&lt;/code&gt; attribute:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[rustc_on_unimplemented(&lt;/span&gt;
&lt;span class="nd"&gt;message&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"The type `{Self}` does not implement `MyTrait`. Please ensure that `{Self}` provides an implementation for `my_method`."&lt;/span&gt;&lt;span class="nd"&gt;,&lt;/span&gt;
&lt;span class="nd"&gt;note&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Implement the `my_method` function for `{Self}` to satisfy the `MyTrait` requirement."&lt;/span&gt;&lt;span class="nd"&gt;,&lt;/span&gt;
&lt;span class="nd"&gt;label&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"missing implementation for `my_method`"&lt;/span&gt;
&lt;span class="nd"&gt;)]&lt;/span&gt;

&lt;span class="k"&gt;trait&lt;/span&gt; &lt;span class="n"&gt;MyTrait&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;my_method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;MyType&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Implement the trait for MyType&lt;/span&gt;
&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;MyTrait&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;MyType&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;my_method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Implementation goes here&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// another type that does not implement MyTrait&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;AnotherType&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// This will trigger the custom error message because AnotherType does not implement MyTrait&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;use_trait&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;MyTrait&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="nf"&gt;.my_method&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;AnotherType&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nf"&gt;use_trait&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// This line will cause a compile-time error with the custom message&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, attempting to use &lt;code&gt;AnotherType&lt;/code&gt; with the &lt;code&gt;use_trait&lt;/code&gt; function will trigger the custom error message because &lt;code&gt;AnotherType&lt;/code&gt; does not implement &lt;code&gt;MyTrait&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Benefits
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Improved Developer Experience&lt;/strong&gt;: By providing more specific and helpful error messages, developers can more quickly understand and resolve issues in their code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enhanced Code Clarity&lt;/strong&gt;: Custom diagnostic messages can include additional context and explanations, making it easier to understand the requirements and constraints of your code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consistency&lt;/strong&gt;: Collecting diagnostic attributes in a common namespace makes it easier for users to find and apply them, and for the language team to establish consistent rules and guidelines.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The introduction of diagnostic attributes in Rust represents a significant step forward in enhancing the developer experience. By allowing for customized and context-specific error messages, Rust continues to uphold its reputation for providing helpful and user-friendly compiler diagnostics. As you adopt these new features, you'll find that your code becomes not only more robust but also more accessible to others in the Rust community.&lt;/p&gt;

&lt;p&gt;For more detailed information, you can refer to the official Rust documentation and the RFC that introduced this feature.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://rust-lang.github.io/rfcs/3368-diagnostic-attribute-namespace.html"&gt;https://rust-lang.github.io/rfcs/3368-diagnostic-attribute-namespace.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://doc.rust-lang.org/reference/attributes.html"&gt;https://doc.rust-lang.org/reference/attributes.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>rust</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Writing Rust Documentation</title>
      <dc:creator>Maksim Gritchin</dc:creator>
      <pubDate>Wed, 12 Jun 2024 13:49:30 +0000</pubDate>
      <link>https://forem.com/gritmax/writing-rust-documentation-5hn5</link>
      <guid>https://forem.com/gritmax/writing-rust-documentation-5hn5</guid>
      <description>&lt;p&gt;Writing effective documentation is crucial for any programming language, and Rust is no exception. Good documentation helps users understand how to use your code, what it does, and why it matters. In this guide, I'll walk you through the best practices for writing documentation in Rust, ensuring that your code is not only functional but also accessible and user-friendly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction to Rust Documentation
&lt;/h2&gt;

&lt;p&gt;Rust documentation is typically written using &lt;code&gt;rustdoc&lt;/code&gt;, a tool that generates HTML documentation from comments in your source code. The primary goal of &lt;code&gt;rustdoc&lt;/code&gt; is to make it easy for developers like you and me to document our code in a way that is both comprehensive and easy to understand.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Documentation Matters
&lt;/h3&gt;

&lt;p&gt;Documentation serves several key purposes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Communication&lt;/strong&gt;: It explains what your code does, how it works, and how to use it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Maintenance&lt;/strong&gt;: It helps future developers (including yourself) understand the codebase, making it easier to maintain and extend.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Onboarding&lt;/strong&gt;: It aids new team members in getting up to speed with the project.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Community&lt;/strong&gt;: It allows the broader community to use and contribute to your project.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Writing Documentation in Rust
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Commenting Your Code
&lt;/h3&gt;

&lt;p&gt;Rust uses three types of comments for documentation:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Line comments&lt;/strong&gt;: Start with &lt;code&gt;//&lt;/code&gt; and are used for short, single-line comments.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Block comments&lt;/strong&gt;: Enclosed in &lt;code&gt;/* ... */&lt;/code&gt; and can span multiple lines.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Doc comments&lt;/strong&gt;: Start with &lt;code&gt;///&lt;/code&gt; for item-level documentation or &lt;code&gt;//!&lt;/code&gt; for module-level documentation.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Item-Level Documentation
&lt;/h4&gt;

&lt;p&gt;Item-level documentation comments (&lt;code&gt;///&lt;/code&gt;) are used to describe functions, structs, enums, traits, and other items. These comments should be placed directly above the item they describe.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;In this example, the &lt;code&gt;add&lt;/code&gt; function is documented with a brief description and an example of how to use it. The &lt;code&gt;# Examples&lt;/code&gt; section is a common convention in Rust documentation, providing a clear and concise way to demonstrate usage.&lt;/p&gt;

&lt;h4&gt;
  
  
  Module-Level Documentation
&lt;/h4&gt;

&lt;p&gt;Module-level documentation comments (&lt;code&gt;//!&lt;/code&gt;) are used to describe the overall purpose and functionality of a module. These comments should be placed at the top of the module file.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Here, the module-level comment provides a high-level overview of the module's purpose, while the item-level comments describe the individual functions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Structuring Your Documentation
&lt;/h3&gt;

&lt;p&gt;Good documentation is well-structured and easy to navigate. Here are some tips for structuring your Rust documentation:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Use Sections&lt;/strong&gt;: Break your documentation into sections using headings. Common sections include &lt;code&gt;# Examples&lt;/code&gt;, &lt;code&gt;# Panics&lt;/code&gt;, &lt;code&gt;# Errors&lt;/code&gt;, and &lt;code&gt;# Safety&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Provide Examples&lt;/strong&gt;: Examples are one of the most effective ways to demonstrate how to use your code. Include them wherever possible.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Explain Edge Cases&lt;/strong&gt;: Document any edge cases or special conditions that users need to be aware of.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Link to Related Items&lt;/strong&gt;: Use intra-doc links to connect related items within your documentation. This helps users navigate your documentation more easily.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Using Sections
&lt;/h4&gt;

&lt;p&gt;Sections help organize your documentation and make it easier to read. Here are some common sections you might include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Examples&lt;/strong&gt;: Show how to use the item.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Panics&lt;/strong&gt;: Describe any conditions under which the item might panic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Errors&lt;/strong&gt;: Explain any errors that might be returned.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Safety&lt;/strong&gt;: For &lt;code&gt;unsafe&lt;/code&gt; code, explain why it is safe to use.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;In this example, the &lt;code&gt;divide&lt;/code&gt; function documentation includes an &lt;code&gt;# Examples&lt;/code&gt; section to show how to use the function and a &lt;code&gt;# Panics&lt;/code&gt; section to describe a condition that will cause the function to panic.&lt;/p&gt;

&lt;h4&gt;
  
  
  Providing Examples
&lt;/h4&gt;

&lt;p&gt;Examples are crucial for helping users understand how to use your code. They should be simple, clear, and demonstrate the most common use cases.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;This example shows how to calculate the factorial of a number, providing a clear and concise example of how to use the &lt;code&gt;factorial&lt;/code&gt; function.&lt;/p&gt;

&lt;h4&gt;
  
  
  Explaining Edge Cases
&lt;/h4&gt;

&lt;p&gt;Edge cases are situations that occur outside of normal operating conditions. Documenting these cases helps users understand how your code behaves in less common scenarios.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;In this example, the &lt;code&gt;fibonacci&lt;/code&gt; function documentation includes a &lt;code&gt;# Panics&lt;/code&gt; section to explain that the function will panic if the input is too large.&lt;/p&gt;

&lt;h4&gt;
  
  
  Linking to Related Items
&lt;/h4&gt;

&lt;p&gt;Intra-doc links allow you to create hyperlinks to other items within your documentation. This helps users navigate your documentation more easily.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;In this example, the &lt;code&gt;add&lt;/code&gt; and &lt;code&gt;subtract&lt;/code&gt; functions link to each other using intra-doc links, making it easy for users to navigate between related items.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using the &lt;code&gt;#[doc]&lt;/code&gt; Attribute
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;#[doc]&lt;/code&gt; attribute in Rust provides additional flexibility for writing documentation. You can use it to add documentation to items in a more programmatic way. This attribute is particularly useful when you need to generate documentation dynamically or when you want to include documentation that isn't directly tied to a specific item.&lt;/p&gt;

&lt;h4&gt;
  
  
  Basic Usage
&lt;/h4&gt;

&lt;p&gt;The &lt;code&gt;#[doc]&lt;/code&gt; attribute can be used to add documentation to any item. Here's a simple example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[doc&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Adds two numbers together."&lt;/span&gt;&lt;span class="nd"&gt;]&lt;/span&gt; 
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This is equivalent to using the &lt;code&gt;///&lt;/code&gt; comment style but allows for more complex scenarios.&lt;/p&gt;
&lt;h4&gt;
  
  
  Including External Files
&lt;/h4&gt;

&lt;p&gt;You can use the &lt;code&gt;#[doc]&lt;/code&gt; attribute to include documentation from external files. This is useful if you have large blocks of documentation that you want to keep separate from your code.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[doc&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;include_str&lt;/span&gt;&lt;span class="err"&gt;!&lt;/span&gt;&lt;span class="nd"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"docs/add_function.md"&lt;/span&gt;&lt;span class="nd"&gt;)]&lt;/span&gt; 
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;In this example, the documentation for the &lt;code&gt;add&lt;/code&gt; function is included from an external Markdown file.&lt;/p&gt;
&lt;h4&gt;
  
  
  Conditional Documentation
&lt;/h4&gt;

&lt;p&gt;The &lt;code&gt;#[doc]&lt;/code&gt; attribute can also be used to conditionally include documentation based on compile-time conditions. This is useful for documenting platform-specific behavior or features.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[cfg(target_os&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"windows"&lt;/span&gt;&lt;span class="nd"&gt;)]&lt;/span&gt; 
&lt;span class="nd"&gt;#[doc&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"This function is only available on Windows."&lt;/span&gt;&lt;span class="nd"&gt;]&lt;/span&gt; 
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;windows_only_function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// Windows-specific code } &lt;/span&gt;

&lt;span class="nd"&gt;#[cfg(target_os&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"linux"&lt;/span&gt;&lt;span class="nd"&gt;)]&lt;/span&gt; 
&lt;span class="nd"&gt;#[doc&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"This function is only available on Linux."&lt;/span&gt;&lt;span class="nd"&gt;]&lt;/span&gt; 
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;linux_only_function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// Linux-specific code }&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;In this example, different documentation is included based on the target operating system.&lt;/p&gt;
&lt;h3&gt;
  
  
  Best Practices for Writing Documentation
&lt;/h3&gt;

&lt;p&gt;Here are some best practices to keep in mind when writing Rust documentation:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Be Clear and Concise&lt;/strong&gt;: Write in a clear and concise manner. Avoid unnecessary jargon and keep sentences short and to the point.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use Proper Grammar and Spelling&lt;/strong&gt;: Ensure your documentation is free of grammatical and spelling errors. This helps maintain a professional appearance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Be Consistent&lt;/strong&gt;: Use consistent terminology and formatting throughout your documentation. This makes it easier for users to understand and follow.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keep It Up to Date&lt;/strong&gt;: Regularly update your documentation to reflect changes in your code. Outdated documentation can be more harmful than no documentation at all.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use Code Examples&lt;/strong&gt;: Include code examples wherever possible. They are one of the most effective ways to demonstrate how to use your code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Document All Public Items&lt;/strong&gt;: Ensure that all public items (functions, structs, enums, etc.) are documented. This helps users understand how to use your library or application.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  Example of Comprehensive Documentation
&lt;/h3&gt;

&lt;p&gt;Let's put it all together with a comprehensive example:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;In this example, the module-level comment provides an overview of the module, and each function is documented with a description, examples, and any relevant panics.&lt;/p&gt;

&lt;h2&gt;
  
  
  Documentation Tests
&lt;/h2&gt;

&lt;p&gt;One of the powerful features of Rust's documentation system is the ability to include tests directly within your documentation comments. These are known as documentation tests, and they serve a dual purpose: they provide examples of how to use your code and ensure that the examples remain correct as your code evolves.&lt;/p&gt;

&lt;h3&gt;
  
  
  Writing Documentation Tests
&lt;/h3&gt;

&lt;p&gt;To write a documentation test, you simply include code examples within triple backticks in your doc comments. Rust's &lt;code&gt;rustdoc&lt;/code&gt; tool will automatically extract these examples and run them as tests when you run &lt;code&gt;cargo test&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Here's a basic example:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;In this example, the code within the triple backticks is a documentation test. When you run &lt;code&gt;cargo test&lt;/code&gt;, this code will be compiled and executed to ensure that it produces the expected result.&lt;/p&gt;

&lt;h3&gt;
  
  
  Benefits of Documentation Tests
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Ensuring Accuracy&lt;/strong&gt;: Documentation tests ensure that your examples are always accurate and up-to-date. If you change your code in a way that breaks an example, the test will fail, alerting you to the issue.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Providing Working Examples&lt;/strong&gt;: Users can trust that the examples in your documentation actually work, as they are tested alongside your code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reducing Maintenance&lt;/strong&gt;: By embedding tests in your documentation, you reduce the need for separate example code files, making it easier to maintain consistency between your code and its documentation.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Advanced Usage
&lt;/h3&gt;

&lt;p&gt;You can also include multiple examples and more complex scenarios in your documentation tests. Additionally, you can use attributes to control the behavior of these tests.&lt;/p&gt;

&lt;p&gt;For instance, you might want to ignore certain tests or only run them under specific conditions:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;In this example, the second test is ignored because it demonstrates a panic scenario. You can use the &lt;code&gt;ignore&lt;/code&gt; attribute to prevent certain tests from running by default.&lt;/p&gt;

&lt;h3&gt;
  
  
  Running Documentation Tests
&lt;/h3&gt;

&lt;p&gt;To run your documentation tests, simply use the &lt;code&gt;cargo test&lt;/code&gt; command. This will compile and run all tests, including those embedded in your documentation comments.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cargo &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By incorporating documentation tests into your workflow, you can ensure that your documentation remains accurate and useful, providing real value to users of your code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Writing good documentation is an essential skill for any Rust developer. By following the best practices outlined in this guide, you can create documentation that is clear, concise, and helpful to your users. Remember to use &lt;code&gt;rustdoc&lt;/code&gt; to generate your documentation, and keep it up to date as your code evolves. With well-written documentation, you can make your code more accessible, maintainable, and enjoyable to use.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://doc.rust-lang.org/rustdoc/how-to-write-documentation.html"&gt;Rust Book&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>rust</category>
      <category>developer</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
