About Rust

Rust is a systems programming language that is extremely fast, prevents segmentation faults, and is thread-safe. While these features make Rust a powerful tool for systems programming, they also introduce some new concepts that people of other languages ​​may not be familiar with.

In this comprehensive guide, "The Hard Things About Rust ," we aim to shed light on these challenging aspects of Rust and make them understandable to both novice and experienced programmers. We will shed light on these complex concepts and illustrate each concept with concrete examples and real-world scenarios for better understanding.

Here's what we'll cover:

  1. Ownership : We'll start with the basic concept of ownership in Rust. We'll explore what it means to own a value, how ownership is transferred, and how Rust's ownership model helps with memory management.

  2. Borrowing and Lifecycle : Building on the foundation of ownership, we'll delve into borrowing and lifecycle, two interrelated concepts that allow you to refer to data securely.

  3. Slicing : We'll demystify slices, which are views of chunks of memory and are used extensively in Rust to access data efficiently.

  4. Error handling : Rust's approach to errors is unique and robust. We'll introduce Resultand Optiontypes, and how to use them for elegant error handling.

  5. Concurrency : We'll delve into Rust's powerful and sophisticated concurrency model. We'll discuss threads, message passing, and shared state concurrency, among others.

  6. Advanced types and traits : We'll explore some of Rust's advanced types, such as BoxRcArc. We'll also introduce Traits and Trait objects.

  7. Async/Await and Futures : As we move to advanced concepts, we'll explain Rust's async/await syntax and Futures model for handling asynchronous programming.

The goal of this guide is not just to provide an overview of these topics, but to help you understand the rationale behind these concepts, how they work behind the scenes, and how to use them effectively in your Rust programs.

Whether you're a Rust beginner looking to dive deeper into the language, or an intermediate Rustacean looking to solidify your understanding of these complex concepts, this guide is for you. Let's embark on this journey of conquering Rust's difficulties!

ownership

Ownership is a fundamental concept in Rust. It is part of Rust's approach to memory safety and makes Rust unique among programming languages. Understanding ownership is crucial to writing Rust programs, because many other Rust concepts, such as borrowing and lifetimes, are built on top of it.

What is ownership?

In Rust, every value has a variable called its owner . There can only be one owner at a time. The value will be deleted or cleaned up when the owner goes out of scope.

Let's consider a simple example:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-text-color)">{</span>
   <span style="color:var(--syntax-declaration-color)">let</span> <span style="color:var(--syntax-text-color)">s</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-string-color)">"hello world"</span><span style="color:var(--syntax-text-color)">;</span> <span style="color:var(--syntax-comment-color)">// s is the owner of the &str "hello world"</span>
<span style="color:var(--syntax-text-color)">}</span> <span style="color:var(--syntax-comment-color)">// s goes out of scope here, and the string is dropped</span>
</code></span></span>

In the above code, the variable sis the owner of the string "hello world". Once sout of bounds at the end of the block, the string is deleted and its memory is freed.

mobile ownership

In Rust, assignment operators =transfer ownership from one variable to another. =This is different from other languages ​​that copy values.

Consider this example:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-declaration-color)">let</span> <span style="color:var(--syntax-text-color)">s1</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">String</span><span style="color:var(--syntax-text-color)">::</span><span style="color:var(--syntax-name-color)">from</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"hello"</span><span style="color:var(--syntax-text-color)">);</span>
<span style="color:var(--syntax-declaration-color)">let</span> <span style="color:var(--syntax-text-color)">s2</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">s1</span><span style="color:var(--syntax-text-color)">;</span>
</code></span></span>

In the above code, s1string is initially owned  "hello". However, the line let s2 = s1;transfers ownership from s1to s2. Now, s2is the owner of the string "hello"and s1is no longer valid. Rust will give you a compile-time error if you try to use after that s1.

copy trait

Certain types in Rust implement this Copytrait. When such a type is assigned to another variable, ownership is not moved, but a copy of the value is created. All integer and floating point types, boolean types, character types, and type tuples implementing traits Copyare Copy.

Here is an example:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-declaration-color)">let</span> <span style="color:var(--syntax-text-color)">x</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-literal-color)">5</span><span style="color:var(--syntax-text-color)">;</span>
<span style="color:var(--syntax-declaration-color)">let</span> <span style="color:var(--syntax-text-color)">y</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">x</span><span style="color:var(--syntax-text-color)">;</span>
</code></span></span>

In the code above, xis an integer, which implements the Copytrait. So it doesn't move ownership when we write let y = x;. Instead, it copies the value from xto y.

Why ownership?

The concept of ownership enables Rust to make memory safety guarantees without requiring a garbage collector. By enforcing that a value can only have one owner, and that the value is cleared when the owner goes out of scope, Rust prevents common programming errors such as null or dangling pointers, double frees, and data races.

Borrowing and lifetimes: safely referencing data in Rust

Borrowing and lifetimes are two of Rust's most notable features. Together, they enable Rust to be memory-safe and thread-safe without a garbage collector. Let's explore these concepts in detail.

loan

In Rust, we often let other parts of the code access a value without taking ownership of it. This is done through a feature called "borrowing". There are two types of borrowing: shared borrowing and mutable borrowing.

shared borrowing

Shared borrowing allows an item to have multiple references. &This is done using symbols in Rust. Let's look at an example:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-declaration-color)">fn</span> <span style="color:var(--syntax-name-color)">main</span><span style="color:var(--syntax-text-color)">()</span> <span style="color:var(--syntax-text-color)">{</span>
    <span style="color:var(--syntax-declaration-color)">let</span> <span style="color:var(--syntax-text-color)">s1</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">String</span><span style="color:var(--syntax-text-color)">::</span><span style="color:var(--syntax-name-color)">from</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"hello"</span><span style="color:var(--syntax-text-color)">);</span>
    <span style="color:var(--syntax-declaration-color)">let</span> <span style="color:var(--syntax-text-color)">len</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-name-color)">calculate_length</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-error-color)">&</span><span style="color:var(--syntax-text-color)">s1</span><span style="color:var(--syntax-text-color)">);</span>
    <span style="color:var(--syntax-name-color)">println!</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"The length of '{}' is {}."</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-text-color)">s1</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-text-color)">len</span><span style="color:var(--syntax-text-color)">);</span>
<span style="color:var(--syntax-text-color)">}</span>

<span style="color:var(--syntax-declaration-color)">fn</span> <span style="color:var(--syntax-name-color)">calculate_length</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">s</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-error-color)">&</span><span style="color:var(--syntax-text-color)">String</span><span style="color:var(--syntax-text-color)">)</span> <span style="color:var(--syntax-declaration-color)">-></span> <span style="color:var(--syntax-text-color)">usize</span> <span style="color:var(--syntax-text-color)">{</span>
    <span style="color:var(--syntax-text-color)">s</span><span style="color:var(--syntax-name-color)">.len</span><span style="color:var(--syntax-text-color)">()</span>
<span style="color:var(--syntax-text-color)">}</span>
</code></span></span>

In this code, calculate_lengthit is borrowed for s1temporary use. s1still belongs to the mainfunction, so we can s1use it again after calling it calculate_length.

mutable borrow

Mutable borrowing is when you want to allow changing the borrowed value. &mutThis is done by using in front of the variable. For example:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-declaration-color)">fn</span> <span style="color:var(--syntax-name-color)">main</span><span style="color:var(--syntax-text-color)">()</span> <span style="color:var(--syntax-text-color)">{</span>
    <span style="color:var(--syntax-declaration-color)">let</span> <span style="color:var(--syntax-declaration-color)">mut</span> <span style="color:var(--syntax-text-color)">s1</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">String</span><span style="color:var(--syntax-text-color)">::</span><span style="color:var(--syntax-name-color)">from</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"hello"</span><span style="color:var(--syntax-text-color)">);</span>
    <span style="color:var(--syntax-name-color)">change</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-error-color)">&</span><span style="color:var(--syntax-declaration-color)">mut</span> <span style="color:var(--syntax-text-color)">s1</span><span style="color:var(--syntax-text-color)">);</span>
<span style="color:var(--syntax-text-color)">}</span>

<span style="color:var(--syntax-declaration-color)">fn</span> <span style="color:var(--syntax-name-color)">change</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">s</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-error-color)">&</span><span style="color:var(--syntax-declaration-color)">mut</span> <span style="color:var(--syntax-text-color)">String</span><span style="color:var(--syntax-text-color)">)</span> <span style="color:var(--syntax-text-color)">{</span>
    <span style="color:var(--syntax-text-color)">s</span><span style="color:var(--syntax-name-color)">.push_str</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">", world"</span><span style="color:var(--syntax-text-color)">);</span>
<span style="color:var(--syntax-text-color)">}</span>
</code></span></span>

Here, changethe function is borrowing s1and changing it. This is possible because of s1mutable borrowing.

However, Rust has a rule that you can have one mutable reference or any number of immutable references, but not both. This rule guarantees that data races never occur.

Let's break down this concept with a code example.

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-declaration-color)">fn</span> <span style="color:var(--syntax-name-color)">main</span><span style="color:var(--syntax-text-color)">()</span> <span style="color:var(--syntax-text-color)">{</span>
    <span style="color:var(--syntax-declaration-color)">let</span> <span style="color:var(--syntax-declaration-color)">mut</span> <span style="color:var(--syntax-text-color)">s</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">String</span><span style="color:var(--syntax-text-color)">::</span><span style="color:var(--syntax-name-color)">from</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"hello"</span><span style="color:var(--syntax-text-color)">);</span>

    <span style="color:var(--syntax-declaration-color)">let</span> <span style="color:var(--syntax-text-color)">r1</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-error-color)">&</span><span style="color:var(--syntax-text-color)">s</span><span style="color:var(--syntax-text-color)">;</span> <span style="color:var(--syntax-comment-color)">// no problem</span>
    <span style="color:var(--syntax-declaration-color)">let</span> <span style="color:var(--syntax-text-color)">r2</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-error-color)">&</span><span style="color:var(--syntax-text-color)">s</span><span style="color:var(--syntax-text-color)">;</span> <span style="color:var(--syntax-comment-color)">// no problem</span>
    <span style="color:var(--syntax-name-color)">println!</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"{} and {}"</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-text-color)">r1</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-text-color)">r2</span><span style="color:var(--syntax-text-color)">);</span>
    <span style="color:var(--syntax-comment-color)">// r1 and r2 are no longer used after this point</span>

    <span style="color:var(--syntax-declaration-color)">let</span> <span style="color:var(--syntax-text-color)">r3</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-error-color)">&</span><span style="color:var(--syntax-declaration-color)">mut</span> <span style="color:var(--syntax-text-color)">s</span><span style="color:var(--syntax-text-color)">;</span> <span style="color:var(--syntax-comment-color)">// no problem</span>
    <span style="color:var(--syntax-name-color)">println!</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"{}"</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-text-color)">r3</span><span style="color:var(--syntax-text-color)">);</span>
<span style="color:var(--syntax-text-color)">}</span>
</code></span></span>

In this example, the code works fine because even though and are in scope r1at creation time, they are not used r2after creation . Rust's rules state (as stated earlier) that you can have one mutable reference or any number of immutable references, but not both. But this only applies when using references.r3r3

Now, let's look at an example that violates Rust's borrowing rules:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-declaration-color)">fn</span> <span style="color:var(--syntax-name-color)">main</span><span style="color:var(--syntax-text-color)">()</span> <span style="color:var(--syntax-text-color)">{</span>
    <span style="color:var(--syntax-declaration-color)">let</span> <span style="color:var(--syntax-declaration-color)">mut</span> <span style="color:var(--syntax-text-color)">s</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">String</span><span style="color:var(--syntax-text-color)">::</span><span style="color:var(--syntax-name-color)">from</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"hello"</span><span style="color:var(--syntax-text-color)">);</span>

    <span style="color:var(--syntax-declaration-color)">let</span> <span style="color:var(--syntax-text-color)">r1</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-error-color)">&</span><span style="color:var(--syntax-text-color)">s</span><span style="color:var(--syntax-text-color)">;</span> <span style="color:var(--syntax-comment-color)">// no problem</span>
    <span style="color:var(--syntax-declaration-color)">let</span> <span style="color:var(--syntax-text-color)">r2</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-error-color)">&</span><span style="color:var(--syntax-text-color)">s</span><span style="color:var(--syntax-text-color)">;</span> <span style="color:var(--syntax-comment-color)">// no problem</span>
    <span style="color:var(--syntax-declaration-color)">let</span> <span style="color:var(--syntax-text-color)">r3</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-error-color)">&</span><span style="color:var(--syntax-declaration-color)">mut</span> <span style="color:var(--syntax-text-color)">s</span><span style="color:var(--syntax-text-color)">;</span> <span style="color:var(--syntax-comment-color)">// PROBLEM! // cannot borrow `s` as mutable because it is also borrowed as immutable</span>

    <span style="color:var(--syntax-name-color)">println!</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"{}, {}, and {}"</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-text-color)">r1</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-text-color)">r2</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-text-color)">r3</span><span style="color:var(--syntax-text-color)">);</span>
<span style="color:var(--syntax-text-color)">}</span>
</code></span></span>

In this case we have r1and , r2which are immutable references and r3which are mutable references. We're trying to use all of them at the same time, which violates Rust's borrowing rules, so the compiler will throw an error.

This rule prevents data races at compile time.

life

Lifecycles are Rust's way of ensuring that all borrows are valid. The point of lifecycles is to prevent dangling references. A dangling reference occurs when we have a reference to some data, and that data is removed before the reference.

In Rust, the compiler uses lifetimes to ensure that such errors do not occur. Here is an example:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-declaration-color)">fn</span> <span style="color:var(--syntax-text-color)">longest</span><span style="color:var(--syntax-error-color)"><</span><span style="color:var(--syntax-text-color)">'a</span><span style="color:var(--syntax-error-color)">></span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">x</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-error-color)">&</span><span style="color:var(--syntax-text-color)">'a</span> <span style="color:var(--syntax-text-color)">str</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-text-color)">y</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-error-color)">&</span><span style="color:var(--syntax-text-color)">'a</span> <span style="color:var(--syntax-text-color)">str</span><span style="color:var(--syntax-text-color)">)</span> <span style="color:var(--syntax-declaration-color)">-></span> <span style="color:var(--syntax-error-color)">&</span><span style="color:var(--syntax-text-color)">'a</span> <span style="color:var(--syntax-text-color)">str</span> <span style="color:var(--syntax-text-color)">{</span>
    <span style="color:var(--syntax-declaration-color)">if</span> <span style="color:var(--syntax-text-color)">x</span><span style="color:var(--syntax-name-color)">.len</span><span style="color:var(--syntax-text-color)">()</span> <span style="color:var(--syntax-error-color)">></span> <span style="color:var(--syntax-text-color)">y</span><span style="color:var(--syntax-name-color)">.len</span><span style="color:var(--syntax-text-color)">()</span> <span style="color:var(--syntax-text-color)">{</span>
        <span style="color:var(--syntax-text-color)">x</span>
    <span style="color:var(--syntax-text-color)">}</span> <span style="color:var(--syntax-declaration-color)">else</span> <span style="color:var(--syntax-text-color)">{</span>
        <span style="color:var(--syntax-text-color)">y</span>
    <span style="color:var(--syntax-text-color)">}</span>
<span style="color:var(--syntax-text-color)">}</span>
</code></span></span>

In this function, 'ais a lifetime parameter that says: For some lifetime 'a, take two arguments, both of which are slices of strings at least as long as 'a, and return a slice of strings at least as long as 'a.

This is a bit abstract, let's consider a concrete example:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-declaration-color)">fn</span> <span style="color:var(--syntax-name-color)">main</span><span style="color:var(--syntax-text-color)">()</span> <span style="color:var(--syntax-text-color)">{</span>
    <span style="color:var(--syntax-declaration-color)">let</span> <span style="color:var(--syntax-text-color)">string1</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">String</span><span style="color:var(--syntax-text-color)">::</span><span style="color:var(--syntax-name-color)">from</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"long string is long"</span><span style="color:var(--syntax-text-color)">);</span>
    <span style="color:var(--syntax-text-color)">{</span>
        <span style="color:var(--syntax-declaration-color)">let</span> <span style="color:var(--syntax-text-color)">string2</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">String</span><span style="color:var(--syntax-text-color)">::</span><span style="color:var(--syntax-name-color)">from</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"xyz"</span><span style="color:var(--syntax-text-color)">);</span>
        <span style="color:var(--syntax-declaration-color)">let</span> <span style="color:var(--syntax-text-color)">result</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-name-color)">longest</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">string1</span><span style="color:var(--syntax-name-color)">.as_str</span><span style="color:var(--syntax-text-color)">(),</span> <span style="color:var(--syntax-text-color)">string2</span><span style="color:var(--syntax-name-color)">.as_str</span><span style="color:var(--syntax-text-color)">());</span>
        <span style="color:var(--syntax-name-color)">println!</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"The longest string is {}"</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-text-color)">result</span><span style="color:var(--syntax-text-color)">);</span>
    <span style="color:var(--syntax-text-color)">}</span>
<span style="color:var(--syntax-text-color)">}</span>
</code></span></span>

Here, the lifetime of the is string1longer than the lifetime of the string2, so it won't be referenced when resultused in the , making sure we don't have dangling references.println!string2

In summary, borrowing and lifetimes are two sides of the same coin that make Rust safe and efficient. They allow Rust to ensure safety and concurrency at compile time. Understanding them is key to mastering Rust.

Slicing: Sequence Views in Rust

Rust provides a way to refer to a contiguous sequence or part of a collection, rather than the entire collection itself. This is done with a feature called "slicing".

Understanding slices

A slice represents a reference to one or more contiguous elements of a collection, rather than a reference to the entire collection. Here's an example of a slice:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-declaration-color)">fn</span> <span style="color:var(--syntax-name-color)">main</span><span style="color:var(--syntax-text-color)">()</span> <span style="color:var(--syntax-text-color)">{</span>
    <span style="color:var(--syntax-declaration-color)">let</span> <span style="color:var(--syntax-text-color)">s</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">String</span><span style="color:var(--syntax-text-color)">::</span><span style="color:var(--syntax-name-color)">from</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"hello world"</span><span style="color:var(--syntax-text-color)">);</span>
    <span style="color:var(--syntax-declaration-color)">let</span> <span style="color:var(--syntax-text-color)">hello</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-error-color)">&</span><span style="color:var(--syntax-text-color)">s</span><span style="color:var(--syntax-text-color)">[</span><span style="color:var(--syntax-literal-color)">0</span><span style="color:var(--syntax-error-color)">..</span><span style="color:var(--syntax-literal-color)">5</span><span style="color:var(--syntax-text-color)">];</span>
    <span style="color:var(--syntax-declaration-color)">let</span> <span style="color:var(--syntax-text-color)">world</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-error-color)">&</span><span style="color:var(--syntax-text-color)">s</span><span style="color:var(--syntax-text-color)">[</span><span style="color:var(--syntax-literal-color)">6</span><span style="color:var(--syntax-error-color)">..</span><span style="color:var(--syntax-literal-color)">11</span><span style="color:var(--syntax-text-color)">];</span>
    <span style="color:var(--syntax-name-color)">println!</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"{} {}"</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-text-color)">hello</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-text-color)">world</span><span style="color:var(--syntax-text-color)">);</span>
<span style="color:var(--syntax-text-color)">}</span>
</code></span></span>

In this code, helloand worldare slices s. The numbers [0..5] and [6..11] are range indices that mean "start at index 0 and continue up to but not including index 5" and "start at index 6 and continue up to but not including index 11" respectively . If we run this program, it will print hello world.

string slice

A string slice is a reference to a part of a string, it looks like this:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-declaration-color)">let</span> <span style="color:var(--syntax-text-color)">s</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">String</span><span style="color:var(--syntax-text-color)">::</span><span style="color:var(--syntax-name-color)">from</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"hello world"</span><span style="color:var(--syntax-text-color)">);</span>
<span style="color:var(--syntax-declaration-color)">let</span> <span style="color:var(--syntax-text-color)">hello</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-error-color)">&</span><span style="color:var(--syntax-text-color)">s</span><span style="color:var(--syntax-text-color)">[</span><span style="color:var(--syntax-literal-color)">0</span><span style="color:var(--syntax-error-color)">..</span><span style="color:var(--syntax-literal-color)">5</span><span style="color:var(--syntax-text-color)">];</span>
<span style="color:var(--syntax-declaration-color)">let</span> <span style="color:var(--syntax-text-color)">world</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-error-color)">&</span><span style="color:var(--syntax-text-color)">s</span><span style="color:var(--syntax-text-color)">[</span><span style="color:var(--syntax-literal-color)">6</span><span style="color:var(--syntax-error-color)">..</span><span style="color:var(--syntax-literal-color)">11</span><span style="color:var(--syntax-text-color)">];</span>
</code></span></span>

Here helloand worldare slices of strings s. You can create slices by specifying [starting_index..ending_index] using ranges enclosed in brackets, where starting_indexis the first position in the slice and ending_indexone more than the last position in the slice.

array slice

Just like strings, we can also slice arrays. Here is an example:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-declaration-color)">fn</span> <span style="color:var(--syntax-name-color)">main</span><span style="color:var(--syntax-text-color)">()</span> <span style="color:var(--syntax-text-color)">{</span>
    <span style="color:var(--syntax-declaration-color)">let</span> <span style="color:var(--syntax-text-color)">a</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">[</span><span style="color:var(--syntax-literal-color)">1</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-literal-color)">2</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-literal-color)">3</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-literal-color)">4</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-literal-color)">5</span><span style="color:var(--syntax-text-color)">];</span>
    <span style="color:var(--syntax-declaration-color)">let</span> <span style="color:var(--syntax-text-color)">slice</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-error-color)">&</span><span style="color:var(--syntax-text-color)">a</span><span style="color:var(--syntax-text-color)">[</span><span style="color:var(--syntax-literal-color)">1</span><span style="color:var(--syntax-error-color)">..</span><span style="color:var(--syntax-literal-color)">3</span><span style="color:var(--syntax-text-color)">];</span>
    <span style="color:var(--syntax-name-color)">println!</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"{:?}"</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-text-color)">slice</span><span style="color:var(--syntax-text-color)">);</span>
<span style="color:var(--syntax-text-color)">}</span>
</code></span></span>

Here, slicewill be a slice 2, 3containing the second and third elements of the array a.

The benefits of slicing

The power of slices is that they allow you to refer to contiguous sequences without copying the sequences into a new collection. This is a more efficient way of having functions access parts of a collection.

Error handling in Rust

Error handling is a fundamental part of any programming language, and Rust is no exception. It recognizes the inevitable bugs in software and provides powerful mechanisms to deal with them efficiently. The design of Rust's error handling mechanism requires developers to explicitly acknowledge and handle errors, making programs more robust and preventing many problems from affecting production environments.

Rust divides errors into two broad categories: recoverable errors and unrecoverable errors. Recoverable errors are usually the result of operations that would normally fail, such as attempting to open a file that does not exist. In such cases, we usually want to notify the user of the error and retry the operation or continue the program differently.

Unrecoverable errors, on the other hand, usually indicate a bug in your code, such as trying to access an array outside its bounds. These types of errors are severe enough to warrant stopping the program immediately.

Interestingly, Rust doesn't use exceptions, which is a common error handling mechanism in many languages. Instead, it provides two constructs: Result<T, E>and panic!macros, for handling recoverable and unrecoverable errors, respectively.

panic!the macro

Macros in Rust panic!are used to stop the execution of a program immediately. It's usually used when a program encounters a situation it doesn't know how to handle or when it reaches a state it should never have reached. These scenarios usually represent bugs in the program. When called panic!, error messages are printed to standard error output, and the program terminates.

You can panic!call it with a simple string message, or use it with a format string, something like . println!The message you pass to will panic!become the urgent payload and be returned as part of the error message when the program crashes. For example:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-name-color)">panic!</span><span style="color:var(--syntax-text-color)">();</span>
<span style="color:var(--syntax-name-color)">panic!</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"this is a terrible mistake!"</span><span style="color:var(--syntax-text-color)">);</span>
<span style="color:var(--syntax-name-color)">panic!</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"this is a {} {message}"</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-string-color)">"fancy"</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-text-color)">message</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-string-color)">"message"</span><span style="color:var(--syntax-text-color)">);</span>
<span style="color:var(--syntax-text-color)">std</span><span style="color:var(--syntax-text-color)">::</span><span style="color:var(--syntax-text-color)">panic</span><span style="color:var(--syntax-text-color)">::</span><span style="color:var(--syntax-name-color)">panic_any</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-literal-color)">4</span><span style="color:var(--syntax-text-color)">);</span> <span style="color:var(--syntax-comment-color)">// panic with the value of 4 to be collected elsewhere</span>
</code></span></span>

If panic!called in the main thread, it will terminate all other threads and end your program with an exit code 101.

Result<T, E>enumerate

Rust's way of handling recoverable errors is encapsulated in enums Result<T, E>. Resultis a generic enum with two variants: Ok(T)for successful results, Err(E)and for errors. The power of Resultis in its unambiguous nature; it forces the developer to handle both success and failure conditions, thus avoiding many common error-handling pitfalls.

Rust provides several Resultways of manipulating values, the most famous of which are ?operators. Operators ?can be attached to return Result. If the function succeeds and returns Ok(T), ?the operator unwraps the value Tand the program continues. If the function encounters an error and returns Err(E), ?the operator immediately returns from the current function and propagates the error up the call stack.

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-declaration-color)">enum</span> <span style="color:var(--syntax-text-color)">Result</span><span style="color:var(--syntax-error-color)"><</span><span style="color:var(--syntax-text-color)">T</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-text-color)">E</span><span style="color:var(--syntax-error-color)">></span> <span style="color:var(--syntax-text-color)">{</span>
    <span style="color:var(--syntax-name-color)">Ok</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">T</span><span style="color:var(--syntax-text-color)">),</span>
    <span style="color:var(--syntax-name-color)">Err</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">E</span><span style="color:var(--syntax-text-color)">),</span>
<span style="color:var(--syntax-text-color)">}</span>
</code></span></span>

This definition means that a function returning a Resultcan succeed (  Ok) and return a value of type T, or fail (  Err) and return an error of type E.

Here is an example of a function that returns a Result:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-declaration-color)">use</span> <span style="color:var(--syntax-text-color)">std</span><span style="color:var(--syntax-text-color)">::</span><span style="color:var(--syntax-text-color)">num</span><span style="color:var(--syntax-text-color)">::</span><span style="color:var(--syntax-text-color)">ParseIntError</span><span style="color:var(--syntax-text-color)">;</span>

<span style="color:var(--syntax-declaration-color)">fn</span> <span style="color:var(--syntax-name-color)">parse_number</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">s</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-error-color)">&</span><span style="color:var(--syntax-text-color)">str</span><span style="color:var(--syntax-text-color)">)</span> <span style="color:var(--syntax-declaration-color)">-></span> <span style="color:var(--syntax-text-color)">Result</span><span style="color:var(--syntax-error-color)"><</span><span style="color:var(--syntax-text-color)">i32</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-text-color)">ParseIntError</span><span style="color:var(--syntax-error-color)">></span> <span style="color:var(--syntax-text-color)">{</span>
    <span style="color:var(--syntax-declaration-color)">match</span> <span style="color:var(--syntax-text-color)">s</span><span style="color:var(--syntax-text-color)">.parse</span><span style="color:var(--syntax-text-color)">::</span><span style="color:var(--syntax-error-color)"><</span><span style="color:var(--syntax-text-color)">i32</span><span style="color:var(--syntax-error-color)">></span><span style="color:var(--syntax-text-color)">()</span> <span style="color:var(--syntax-text-color)">{</span>
        <span style="color:var(--syntax-name-color)">Ok</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">n</span><span style="color:var(--syntax-text-color)">)</span> <span style="color:var(--syntax-declaration-color)">=></span> <span style="color:var(--syntax-name-color)">Ok</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">n</span><span style="color:var(--syntax-text-color)">),</span>
        <span style="color:var(--syntax-name-color)">Err</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">e</span><span style="color:var(--syntax-text-color)">)</span> <span style="color:var(--syntax-declaration-color)">=></span> <span style="color:var(--syntax-name-color)">Err</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">e</span><span style="color:var(--syntax-text-color)">),</span>
    <span style="color:var(--syntax-text-color)">}</span>
<span style="color:var(--syntax-text-color)">}</span>

<span style="color:var(--syntax-declaration-color)">let</span> <span style="color:var(--syntax-text-color)">n</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-name-color)">parse_number</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"42"</span><span style="color:var(--syntax-text-color)">);</span>
<span style="color:var(--syntax-declaration-color)">match</span> <span style="color:var(--syntax-text-color)">n</span> <span style="color:var(--syntax-text-color)">{</span>
    <span style="color:var(--syntax-name-color)">Ok</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">n</span><span style="color:var(--syntax-text-color)">)</span> <span style="color:var(--syntax-declaration-color)">=></span> <span style="color:var(--syntax-name-color)">println!</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"The number is {}"</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-text-color)">n</span><span style="color:var(--syntax-text-color)">),</span>
    <span style="color:var(--syntax-name-color)">Err</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">e</span><span style="color:var(--syntax-text-color)">)</span> <span style="color:var(--syntax-declaration-color)">=></span> <span style="color:var(--syntax-name-color)">println!</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"Error: {}"</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-text-color)">e</span><span style="color:var(--syntax-text-color)">),</span>
<span style="color:var(--syntax-text-color)">}</span>
</code></span></span>

In this example, parse_numberan attempt is made to parse a string into an integer. If successful, return the number inside Ok, otherwise return the error inside Err. There are two possible outcomes of this matchstatement for processing Result.

options

Enum Optionis similar to Resultbut used when a function can return a value or not at all (instead of an error). It is defined as:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-declaration-color)">enum</span> <span style="color:var(--syntax-text-color)">Option</span><span style="color:var(--syntax-error-color)"><</span><span style="color:var(--syntax-text-color)">T</span><span style="color:var(--syntax-error-color)">></span> <span style="color:var(--syntax-text-color)">{</span>
    <span style="color:var(--syntax-name-color)">Some</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">T</span><span style="color:var(--syntax-text-color)">),</span>
    <span style="color:var(--syntax-text-color)">None</span><span style="color:var(--syntax-text-color)">,</span>
<span style="color:var(--syntax-text-color)">}</span>
</code></span></span>

Here's an example of a function that returns Option:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-declaration-color)">fn</span> <span style="color:var(--syntax-name-color)">find</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">array</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-error-color)">&</span><span style="color:var(--syntax-text-color)">[</span><span style="color:var(--syntax-text-color)">i32</span><span style="color:var(--syntax-text-color)">],</span> <span style="color:var(--syntax-text-color)">target</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-text-color)">i32</span><span style="color:var(--syntax-text-color)">)</span> <span style="color:var(--syntax-declaration-color)">-></span> <span style="color:var(--syntax-text-color)">Option</span><span style="color:var(--syntax-error-color)"><</span><span style="color:var(--syntax-text-color)">usize</span><span style="color:var(--syntax-error-color)">></span> <span style="color:var(--syntax-text-color)">{</span>
    <span style="color:var(--syntax-declaration-color)">for</span> <span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">index</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-error-color)">&</span><span style="color:var(--syntax-text-color)">item</span><span style="color:var(--syntax-text-color)">)</span> <span style="color:var(--syntax-declaration-color)">in</span> <span style="color:var(--syntax-text-color)">array</span><span style="color:var(--syntax-name-color)">.iter</span><span style="color:var(--syntax-text-color)">()</span><span style="color:var(--syntax-name-color)">.enumerate</span><span style="color:var(--syntax-text-color)">()</span> <span style="color:var(--syntax-text-color)">{</span>
        <span style="color:var(--syntax-declaration-color)">if</span> <span style="color:var(--syntax-text-color)">item</span> <span style="color:var(--syntax-error-color)">==</span> <span style="color:var(--syntax-text-color)">target</span> <span style="color:var(--syntax-text-color)">{</span>
            <span style="color:var(--syntax-declaration-color)">return</span> <span style="color:var(--syntax-name-color)">Some</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">index</span><span style="color:var(--syntax-text-color)">);</span>
        <span style="color:var(--syntax-text-color)">}</span>
    <span style="color:var(--syntax-text-color)">}</span>
    <span style="color:var(--syntax-text-color)">None</span>
<span style="color:var(--syntax-text-color)">}</span>

<span style="color:var(--syntax-declaration-color)">let</span> <span style="color:var(--syntax-text-color)">array</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">[</span><span style="color:var(--syntax-literal-color)">1</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-literal-color)">2</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-literal-color)">3</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-literal-color)">4</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-literal-color)">5</span><span style="color:var(--syntax-text-color)">];</span>
<span style="color:var(--syntax-declaration-color)">match</span> <span style="color:var(--syntax-name-color)">find</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-error-color)">&</span><span style="color:var(--syntax-text-color)">array</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-literal-color)">3</span><span style="color:var(--syntax-text-color)">)</span> <span style="color:var(--syntax-text-color)">{</span>
    <span style="color:var(--syntax-name-color)">Some</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">index</span><span style="color:var(--syntax-text-color)">)</span> <span style="color:var(--syntax-declaration-color)">=></span> <span style="color:var(--syntax-name-color)">println!</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"Found at index {}"</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-text-color)">index</span><span style="color:var(--syntax-text-color)">),</span>
    <span style="color:var(--syntax-text-color)">None</span> <span style="color:var(--syntax-declaration-color)">=></span> <span style="color:var(--syntax-name-color)">println!</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"Not found"</span><span style="color:var(--syntax-text-color)">),</span>
<span style="color:var(--syntax-text-color)">}</span>
</code></span></span>

In this example, the findfunction tries to find a number in an array. If found, the function returns Some(index), where indexis the position of the number in the array. If not found, the function returns None.

and Resultboth Optionprovide various useful methods for working with these types. For example, unwrapcan be used to get Okthe value inside or , but Someconfusion occurs if is or the is . As a safer alternative, and can be used to provide default values ​​or fallback functions, respectively.ResultErrOptionNoneunwrap_orunwrap_or_else

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-declaration-color)">let</span> <span style="color:var(--syntax-text-color)">x</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-name-color)">Some</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-literal-color)">2</span><span style="color:var(--syntax-text-color)">);</span>
<span style="color:var(--syntax-name-color)">assert_eq!</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">x</span><span style="color:var(--syntax-name-color)">.unwrap</span><span style="color:var(--syntax-text-color)">(),</span> <span style="color:var(--syntax-literal-color)">2</span><span style="color:var(--syntax-text-color)">);</span>

<span style="color:var(--syntax-declaration-color)">let</span> <span style="color:var(--syntax-text-color)">x</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-text-color)">Option</span><span style="color:var(--syntax-error-color)"><</span><span style="color:var(--syntax-text-color)">u32</span><span style="color:var(--syntax-error-color)">></span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">None</span><span style="color:var(--syntax-text-color)">;</span>
<span style="color:var(--syntax-name-color)">assert_eq!</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">x</span><span style="color:var(--syntax-name-color)">.unwrap_or</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-literal-color)">42</span><span style="color:var(--syntax-text-color)">),</span> <span style="color:var(--syntax-literal-color)">42</span><span style="color:var(--syntax-text-color)">);</span>

<span style="color:var(--syntax-declaration-color)">let</span> <span style="color:var(--syntax-text-color)">x</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-text-color)">Result</span><span style="color:var(--syntax-error-color)"><</span><span style="color:var(--syntax-text-color)">u32</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-error-color)">&</span><span style="color:var(--syntax-text-color)">str</span><span style="color:var(--syntax-error-color)">></span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-name-color)">Err</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"emergency failure"</span><span style="color:var(--syntax-text-color)">);</span>
<span style="color:var(--syntax-name-color)">assert_eq!</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">x</span><span style="color:var(--syntax-name-color)">.unwrap_or_else</span><span style="color:var(--syntax-text-color)">(|</span><span style="color:var(--syntax-text-color)">_</span><span style="color:var(--syntax-text-color)">|</span> <span style="color:var(--syntax-literal-color)">42</span><span style="color:var(--syntax-text-color)">),</span> <span style="color:var(--syntax-literal-color)">42</span><span style="color:var(--syntax-text-color)">);</span>
</code></span></span>

In general, Resultand Optionare powerful tools in Rust for error handling and representing missing values. They make your code more explicit about possible failure or null conditions, helping to prevent many common programming errors.

concurrency research

Concurrency in Rust is achieved through several mechanisms, including threads, message passing, and shared state. Let's explore each of these in turn.

1. Thread

Rust has a std::threadmodule that allows you to create new threads and use them in a system-independent manner. Here's a simple example of creating a new thread:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-declaration-color)">use</span> <span style="color:var(--syntax-text-color)">std</span><span style="color:var(--syntax-text-color)">::</span><span style="color:var(--syntax-text-color)">thread</span><span style="color:var(--syntax-text-color)">;</span>
<span style="color:var(--syntax-declaration-color)">use</span> <span style="color:var(--syntax-text-color)">std</span><span style="color:var(--syntax-text-color)">::</span><span style="color:var(--syntax-text-color)">time</span><span style="color:var(--syntax-text-color)">::</span><span style="color:var(--syntax-text-color)">Duration</span><span style="color:var(--syntax-text-color)">;</span>

<span style="color:var(--syntax-declaration-color)">fn</span> <span style="color:var(--syntax-name-color)">main</span><span style="color:var(--syntax-text-color)">()</span> <span style="color:var(--syntax-text-color)">{</span>
    <span style="color:var(--syntax-text-color)">thread</span><span style="color:var(--syntax-text-color)">::</span><span style="color:var(--syntax-name-color)">spawn</span><span style="color:var(--syntax-text-color)">(||</span> <span style="color:var(--syntax-text-color)">{</span>
        <span style="color:var(--syntax-declaration-color)">for</span> <span style="color:var(--syntax-text-color)">i</span> <span style="color:var(--syntax-declaration-color)">in</span> <span style="color:var(--syntax-literal-color)">1</span><span style="color:var(--syntax-error-color)">..</span><span style="color:var(--syntax-literal-color)">10</span> <span style="color:var(--syntax-text-color)">{</span>
            <span style="color:var(--syntax-name-color)">println!</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"hi number {} from the spawned thread!"</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-text-color)">i</span><span style="color:var(--syntax-text-color)">);</span>
            <span style="color:var(--syntax-text-color)">thread</span><span style="color:var(--syntax-text-color)">::</span><span style="color:var(--syntax-name-color)">sleep</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">Duration</span><span style="color:var(--syntax-text-color)">::</span><span style="color:var(--syntax-name-color)">from_millis</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-literal-color)">1</span><span style="color:var(--syntax-text-color)">));</span>
        <span style="color:var(--syntax-text-color)">}</span>
    <span style="color:var(--syntax-text-color)">});</span>

    <span style="color:var(--syntax-declaration-color)">for</span> <span style="color:var(--syntax-text-color)">i</span> <span style="color:var(--syntax-declaration-color)">in</span> <span style="color:var(--syntax-literal-color)">1</span><span style="color:var(--syntax-error-color)">..</span><span style="color:var(--syntax-literal-color)">5</span> <span style="color:var(--syntax-text-color)">{</span>
        <span style="color:var(--syntax-name-color)">println!</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"hi number {} from the main thread!"</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-text-color)">i</span><span style="color:var(--syntax-text-color)">);</span>
        <span style="color:var(--syntax-text-color)">thread</span><span style="color:var(--syntax-text-color)">::</span><span style="color:var(--syntax-name-color)">sleep</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">Duration</span><span style="color:var(--syntax-text-color)">::</span><span style="color:var(--syntax-name-color)">from_millis</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-literal-color)">1</span><span style="color:var(--syntax-text-color)">));</span>
    <span style="color:var(--syntax-text-color)">}</span>
<span style="color:var(--syntax-text-color)">}</span>
</code></span></span>

In this example, we create a new thread and thread::spawnpass it a closure containing the new thread's instructions. The main thread and the new thread print their messages independently, sleeping for a millisecond between each message.

2. Messaging

Rust provides a message-passing concurrency model inspired by the Erlang language. Message passing is a method of dealing with concurrency in which threads or actors communicate by sending each other messages containing data.

In Rust, you can use this module to create channels std::sync::mpsc(mpsc stands for multiple producers, single consumer). Here is an example:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-declaration-color)">use</span> <span style="color:var(--syntax-text-color)">std</span><span style="color:var(--syntax-text-color)">::</span><span style="color:var(--syntax-text-color)">sync</span><span style="color:var(--syntax-text-color)">::</span><span style="color:var(--syntax-text-color)">mpsc</span><span style="color:var(--syntax-text-color)">;</span>
<span style="color:var(--syntax-declaration-color)">use</span> <span style="color:var(--syntax-text-color)">std</span><span style="color:var(--syntax-text-color)">::</span><span style="color:var(--syntax-text-color)">thread</span><span style="color:var(--syntax-text-color)">;</span>

<span style="color:var(--syntax-declaration-color)">fn</span> <span style="color:var(--syntax-name-color)">main</span><span style="color:var(--syntax-text-color)">()</span> <span style="color:var(--syntax-text-color)">{</span>
    <span style="color:var(--syntax-declaration-color)">let</span> <span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">tx</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-text-color)">rx</span><span style="color:var(--syntax-text-color)">)</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">mpsc</span><span style="color:var(--syntax-text-color)">::</span><span style="color:var(--syntax-name-color)">channel</span><span style="color:var(--syntax-text-color)">();</span>

    <span style="color:var(--syntax-text-color)">thread</span><span style="color:var(--syntax-text-color)">::</span><span style="color:var(--syntax-name-color)">spawn</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-declaration-color)">move</span> <span style="color:var(--syntax-text-color)">||</span> <span style="color:var(--syntax-text-color)">{</span>
        <span style="color:var(--syntax-declaration-color)">let</span> <span style="color:var(--syntax-text-color)">val</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">String</span><span style="color:var(--syntax-text-color)">::</span><span style="color:var(--syntax-name-color)">from</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"hi"</span><span style="color:var(--syntax-text-color)">);</span>
        <span style="color:var(--syntax-text-color)">tx</span><span style="color:var(--syntax-name-color)">.send</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">val</span><span style="color:var(--syntax-text-color)">)</span><span style="color:var(--syntax-name-color)">.unwrap</span><span style="color:var(--syntax-text-color)">();</span>
    <span style="color:var(--syntax-text-color)">});</span>

    <span style="color:var(--syntax-declaration-color)">let</span> <span style="color:var(--syntax-text-color)">received</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">rx</span><span style="color:var(--syntax-name-color)">.recv</span><span style="color:var(--syntax-text-color)">()</span><span style="color:var(--syntax-name-color)">.unwrap</span><span style="color:var(--syntax-text-color)">();</span>
    <span style="color:var(--syntax-name-color)">println!</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"Got: {}"</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-text-color)">received</span><span style="color:var(--syntax-text-color)">);</span>
<span style="color:var(--syntax-text-color)">}</span>
</code></span></span>

In this example, we create a channel with mpsc::channel, and then move the transport (  tx) into a new thread. This thread sends a message ("hi") to the channel, and we wait to receive that message in the main thread and print it.

3. Shared state

Rust also provides a way to share state between threads in a safe way using mutexes. A mutex provides mutual exclusion, meaning only one thread can access data at any given time. To access data, a thread must first signal that it wants access by asking the mutex to be locked. Here is an example:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-declaration-color)">use</span> <span style="color:var(--syntax-text-color)">std</span><span style="color:var(--syntax-text-color)">::</span><span style="color:var(--syntax-text-color)">sync</span><span style="color:var(--syntax-text-color)">::{</span><span style="color:var(--syntax-text-color)">Mutex</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-text-color)">Arc</span><span style="color:var(--syntax-text-color)">};</span>
<span style="color:var(--syntax-declaration-color)">use</span> <span style="color:var(--syntax-text-color)">std</span><span style="color:var(--syntax-text-color)">::</span><span style="color:var(--syntax-text-color)">thread</span><span style="color:var(--syntax-text-color)">;</span>

<span style="color:var(--syntax-declaration-color)">fn</span> <span style="color:var(--syntax-name-color)">main</span><span style="color:var(--syntax-text-color)">()</span> <span style="color:var(--syntax-text-color)">{</span>
    <span style="color:var(--syntax-declaration-color)">let</span> <span style="color:var(--syntax-text-color)">counter</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">Arc</span><span style="color:var(--syntax-text-color)">::</span><span style="color:var(--syntax-name-color)">new</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">Mutex</span><span style="color:var(--syntax-text-color)">::</span><span style="color:var(--syntax-name-color)">new</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-literal-color)">0</span><span style="color:var(--syntax-text-color)">));</span>
    <span style="color:var(--syntax-declaration-color)">let</span> <span style="color:var(--syntax-declaration-color)">mut</span> <span style="color:var(--syntax-text-color)">handles</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-name-color)">vec!</span><span style="color:var(--syntax-text-color)">[];</span>

    <span style="color:var(--syntax-declaration-color)">for</span> <span style="color:var(--syntax-text-color)">_</span> <span style="color:var(--syntax-declaration-color)">in</span> <span style="color:var(--syntax-literal-color)">0</span><span style="color:var(--syntax-error-color)">..</span><span style="color:var(--syntax-literal-color)">10</span> <span style="color:var(--syntax-text-color)">{</span>
        <span style="color:var(--syntax-declaration-color)">let</span> <span style="color:var(--syntax-text-color)">counter</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">Arc</span><span style="color:var(--syntax-text-color)">::</span><span style="color:var(--syntax-name-color)">clone</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-error-color)">&</span><span style="color:var(--syntax-text-color)">counter</span><span style="color:var(--syntax-text-color)">);</span>
        <span style="color:var(--syntax-declaration-color)">let</span> <span style="color:var(--syntax-text-color)">handle</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">thread</span><span style="color:var(--syntax-text-color)">::</span><span style="color:var(--syntax-name-color)">spawn</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-declaration-color)">move</span> <span style="color:var(--syntax-text-color)">||</span> <span style="color:var(--syntax-text-color)">{</span>
            <span style="color:var(--syntax-declaration-color)">let</span> <span style="color:var(--syntax-declaration-color)">mut</span> <span style="color:var(--syntax-text-color)">num</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">counter</span><span style="color:var(--syntax-name-color)">.lock</span><span style="color:var(--syntax-text-color)">()</span><span style="color:var(--syntax-name-color)">.unwrap</span><span style="color:var(--syntax-text-color)">();</span>

            <span style="color:var(--syntax-error-color)">*</span><span style="color:var(--syntax-text-color)">num</span> <span style="color:var(--syntax-error-color)">+=</span> <span style="color:var(--syntax-literal-color)">1</span><span style="color:var(--syntax-text-color)">;</span>
        <span style="color:var(--syntax-text-color)">});</span>
        <span style="color:var(--syntax-text-color)">handles</span><span style="color:var(--syntax-name-color)">.push</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">handle</span><span style="color:var(--syntax-text-color)">);</span>
    <span style="color:var(--syntax-text-color)">}</span>

    <span style="color:var(--syntax-declaration-color)">for</span> <span style="color:var(--syntax-text-color)">handle</span> <span style="color:var(--syntax-declaration-color)">in</span> <span style="color:var(--syntax-text-color)">handles</span> <span style="color:var(--syntax-text-color)">{</span>
        <span style="color:var(--syntax-text-color)">handle</span><span style="color:var(--syntax-name-color)">.join</span><span style="color:var(--syntax-text-color)">()</span><span style="color:var(--syntax-name-color)">.unwrap</span><span style="color:var(--syntax-text-color)">();</span>
    <span style="color:var(--syntax-text-color)">}</span>

    <span style="color:var(--syntax-name-color)">println!</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"Result: {}"</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-error-color)">*</span><span style="color:var(--syntax-text-color)">counter</span><span style="color:var(--syntax-name-color)">.lock</span><span style="color:var(--syntax-text-color)">()</span><span style="color:var(--syntax-name-color)">.unwrap</span><span style="color:var(--syntax-text-color)">());</span>
<span style="color:var(--syntax-text-color)">}</span>
</code></span></span>

In this example, we create a counter inside a mutex and then use atomic reference counting (Arc) to share it among multiple threads. Each thread locks the mutex, increments the counter, and releases the lock.

This is a high-level overview. Rust's concurrency model is very powerful and flexible, and it provides a number of features to ensure that concurrent code is free from data races and other common concurrency problems.

Advanced Types and Traits

Box

Box is a smart pointer that points to data stored on the heap, not the stack. They are useful when you have a large amount of data to store or you want to ensure that certain variables are not moved around in memory.

Boxes also have ownership. When the Box goes out of scope, the destructor is called and the heap memory is freed.

Here's a simple example:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-declaration-color)">let</span> <span style="color:var(--syntax-text-color)">b</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">Box</span><span style="color:var(--syntax-text-color)">::</span><span style="color:var(--syntax-name-color)">new</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-literal-color)">5</span><span style="color:var(--syntax-text-color)">);</span> <span style="color:var(--syntax-comment-color)">// b is a pointer to a heap allocated integer</span>
<span style="color:var(--syntax-name-color)">println!</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"b = {}"</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-error-color)">*</span><span style="color:var(--syntax-text-color)">b</span><span style="color:var(--syntax-text-color)">);</span> <span style="color:var(--syntax-comment-color)">// Output: b = 5</span>
</code></span></span>

In this example, the variable is a Box, which bholds an integer on the heap. 5operator *is used to dereference a box, getting the value it points to.

RC

Rc stands for reference count. It's a smart pointer that allows multiple owners by keeping track of the number of references to the value that determines when to clean up. rc is used when we want to allocate some data on the heap to be read by multiple parts of the program, and we cannot determine at compile time which part used the data last.

It should be noted that Rc is only applicable to single-threaded scenarios. Here's a simple example:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-declaration-color)">use</span> <span style="color:var(--syntax-text-color)">std</span><span style="color:var(--syntax-text-color)">::</span><span style="color:var(--syntax-text-color)">rc</span><span style="color:var(--syntax-text-color)">::</span><span style="color:var(--syntax-text-color)">Rc</span><span style="color:var(--syntax-text-color)">;</span>

<span style="color:var(--syntax-declaration-color)">let</span> <span style="color:var(--syntax-text-color)">original</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">Rc</span><span style="color:var(--syntax-text-color)">::</span><span style="color:var(--syntax-name-color)">new</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-literal-color)">5</span><span style="color:var(--syntax-text-color)">);</span>
<span style="color:var(--syntax-declaration-color)">let</span> <span style="color:var(--syntax-text-color)">a</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">Rc</span><span style="color:var(--syntax-text-color)">::</span><span style="color:var(--syntax-name-color)">clone</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-error-color)">&</span><span style="color:var(--syntax-text-color)">original</span><span style="color:var(--syntax-text-color)">);</span>
<span style="color:var(--syntax-declaration-color)">let</span> <span style="color:var(--syntax-text-color)">b</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">Rc</span><span style="color:var(--syntax-text-color)">::</span><span style="color:var(--syntax-name-color)">clone</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-error-color)">&</span><span style="color:var(--syntax-text-color)">original</span><span style="color:var(--syntax-text-color)">);</span>

<span style="color:var(--syntax-name-color)">println!</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"original: {}, a: {}, b: {}"</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-error-color)">*</span><span style="color:var(--syntax-text-color)">original</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-error-color)">*</span><span style="color:var(--syntax-text-color)">a</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-error-color)">*</span><span style="color:var(--syntax-text-color)">b</span><span style="color:var(--syntax-text-color)">);</span> <span style="color:var(--syntax-comment-color)">// Output: original: 5, a: 5, b: 5</span>
</code></span></span>

In this example, the variable is an Rc which originalholds an integer on the heap. 5We can create multiple "clones" of this Rc (they are really just new pointers to the same data, not full copies). Heap memory will be freed when all Rcs go out of scope.

arc

Arc is atomic reference counting. It is the same as Rc, but is safe to use in a multithreaded context. It provides the same functionality as Rc, but uses atomic operations for reference counting. This makes it safe to share between multiple threads, at the cost of a slight performance hit.

Here is an example:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-declaration-color)">use</span> <span style="color:var(--syntax-text-color)">std</span><span style="color:var(--syntax-text-color)">::</span><span style="color:var(--syntax-text-color)">sync</span><span style="color:var(--syntax-text-color)">::</span><span style="color:var(--syntax-text-color)">Arc</span><span style="color:var(--syntax-text-color)">;</span>
<span style="color:var(--syntax-declaration-color)">use</span> <span style="color:var(--syntax-text-color)">std</span><span style="color:var(--syntax-text-color)">::</span><span style="color:var(--syntax-text-color)">thread</span><span style="color:var(--syntax-text-color)">;</span>

<span style="color:var(--syntax-declaration-color)">let</span> <span style="color:var(--syntax-text-color)">original</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">Arc</span><span style="color:var(--syntax-text-color)">::</span><span style="color:var(--syntax-name-color)">new</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-literal-color)">5</span><span style="color:var(--syntax-text-color)">);</span>
<span style="color:var(--syntax-declaration-color)">for</span> <span style="color:var(--syntax-text-color)">_</span> <span style="color:var(--syntax-declaration-color)">in</span> <span style="color:var(--syntax-literal-color)">0</span><span style="color:var(--syntax-error-color)">..</span><span style="color:var(--syntax-literal-color)">10</span> <span style="color:var(--syntax-text-color)">{</span>
    <span style="color:var(--syntax-declaration-color)">let</span> <span style="color:var(--syntax-text-color)">original</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">Arc</span><span style="color:var(--syntax-text-color)">::</span><span style="color:var(--syntax-name-color)">clone</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-error-color)">&</span><span style="color:var(--syntax-text-color)">original</span><span style="color:var(--syntax-text-color)">);</span>
    <span style="color:var(--syntax-text-color)">thread</span><span style="color:var(--syntax-text-color)">::</span><span style="color:var(--syntax-name-color)">spawn</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-declaration-color)">move</span> <span style="color:var(--syntax-text-color)">||</span> <span style="color:var(--syntax-text-color)">{</span>
        <span style="color:var(--syntax-name-color)">println!</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"{}"</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-error-color)">*</span><span style="color:var(--syntax-text-color)">original</span><span style="color:var(--syntax-text-color)">);</span>
    <span style="color:var(--syntax-text-color)">});</span>
<span style="color:var(--syntax-text-color)">}</span>
</code></span></span>

In this example, we use Arc to share a heap-allocated integer among multiple threads. Each thread gets a clone of Arc (a new pointer to the data). When all Arcs go out of scope, the heap memory will be freed.

These types provide more advanced ways to manage memory and data ownership in Rust, enabling more complex data structures and patterns. However, they also add complexity and are harder to get right, so they should be used with caution.

trait

In Rust, a trait is a collection of methods defined for unknown types: Self. They have access to other methods declared in the same trait and are a way to define shared or common behavior. Think of traits as a way of defining the interfaces a type can implement.

Consider this simple example:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-declaration-color)">trait</span> <span style="color:var(--syntax-text-color)">Animal</span> <span style="color:var(--syntax-text-color)">{</span>
    <span style="color:var(--syntax-declaration-color)">fn</span> <span style="color:var(--syntax-name-color)">make_noise</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-error-color)">&</span><span style="color:var(--syntax-declaration-color)">self</span><span style="color:var(--syntax-text-color)">)</span> <span style="color:var(--syntax-declaration-color)">-></span> <span style="color:var(--syntax-text-color)">String</span><span style="color:var(--syntax-text-color)">;</span>
<span style="color:var(--syntax-text-color)">}</span>

<span style="color:var(--syntax-declaration-color)">struct</span> <span style="color:var(--syntax-text-color)">Dog</span><span style="color:var(--syntax-text-color)">;</span>
<span style="color:var(--syntax-declaration-color)">struct</span> <span style="color:var(--syntax-text-color)">Cat</span><span style="color:var(--syntax-text-color)">;</span>

<span style="color:var(--syntax-declaration-color)">impl</span> <span style="color:var(--syntax-text-color)">Animal</span> <span style="color:var(--syntax-declaration-color)">for</span> <span style="color:var(--syntax-text-color)">Dog</span> <span style="color:var(--syntax-text-color)">{</span>
    <span style="color:var(--syntax-declaration-color)">fn</span> <span style="color:var(--syntax-name-color)">make_noise</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-error-color)">&</span><span style="color:var(--syntax-declaration-color)">self</span><span style="color:var(--syntax-text-color)">)</span> <span style="color:var(--syntax-declaration-color)">-></span> <span style="color:var(--syntax-text-color)">String</span> <span style="color:var(--syntax-text-color)">{</span>
        <span style="color:var(--syntax-text-color)">String</span><span style="color:var(--syntax-text-color)">::</span><span style="color:var(--syntax-name-color)">from</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"Woof!"</span><span style="color:var(--syntax-text-color)">)</span>
    <span style="color:var(--syntax-text-color)">}</span>
<span style="color:var(--syntax-text-color)">}</span>

<span style="color:var(--syntax-declaration-color)">impl</span> <span style="color:var(--syntax-text-color)">Animal</span> <span style="color:var(--syntax-declaration-color)">for</span> <span style="color:var(--syntax-text-color)">Cat</span> <span style="color:var(--syntax-text-color)">{</span>
    <span style="color:var(--syntax-declaration-color)">fn</span> <span style="color:var(--syntax-name-color)">make_noise</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-error-color)">&</span><span style="color:var(--syntax-declaration-color)">self</span><span style="color:var(--syntax-text-color)">)</span> <span style="color:var(--syntax-declaration-color)">-></span> <span style="color:var(--syntax-text-color)">String</span> <span style="color:var(--syntax-text-color)">{</span>
        <span style="color:var(--syntax-text-color)">String</span><span style="color:var(--syntax-text-color)">::</span><span style="color:var(--syntax-name-color)">from</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"Meow!"</span><span style="color:var(--syntax-text-color)">)</span>
    <span style="color:var(--syntax-text-color)">}</span>
<span style="color:var(--syntax-text-color)">}</span>
</code></span></span>

In the above example, we Animaldefined a Trait with method  make_noise. We then implement this trait for Dogsum Catstructures, providing their unique functional versions make_noise. We can now Animalcall this function on any type that implements the trait.

Clone and Duplicate Features

Rust provides a number of predefined traits with specific behavior. Two of them are Cloneand Copyfeatures.

This Clonefeature allows explicit duplication of data. This method is called when you want to create a new copy of a type's data, cloneif the type implements that Clonetrait.

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-name-color)">#[derive(Clone)]</span>
<span style="color:var(--syntax-declaration-color)">struct</span> <span style="color:var(--syntax-text-color)">Point</span> <span style="color:var(--syntax-text-color)">{</span>
    <span style="color:var(--syntax-text-color)">x</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-text-color)">i32</span><span style="color:var(--syntax-text-color)">,</span>
    <span style="color:var(--syntax-text-color)">y</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-text-color)">i32</span><span style="color:var(--syntax-text-color)">,</span>
<span style="color:var(--syntax-text-color)">}</span>

<span style="color:var(--syntax-declaration-color)">let</span> <span style="color:var(--syntax-text-color)">p1</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">Point</span> <span style="color:var(--syntax-text-color)">{</span> <span style="color:var(--syntax-text-color)">x</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-literal-color)">1</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-text-color)">y</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-literal-color)">2</span> <span style="color:var(--syntax-text-color)">};</span>
<span style="color:var(--syntax-declaration-color)">let</span> <span style="color:var(--syntax-text-color)">p2</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">p1</span><span style="color:var(--syntax-name-color)">.clone</span><span style="color:var(--syntax-text-color)">();</span>  <span style="color:var(--syntax-comment-color)">// p1 is cloned into p2</span>
</code></span></span>

In this example, Pointstructs implement the trait, so we can use this method Cloneto create a copy of any instance.Pointclone

On the other hand, this Copyfeature allows implicit duplication of data. It is used when we want to be able to make a shallow copy of a value without worrying about ownership. If the type implements the Copytrait, the old variable is still available after assignment.

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-name-color)">#[derive(Copy,</span> <span style="color:var(--syntax-name-color)">Clone)]</span>
<span style="color:var(--syntax-declaration-color)">struct</span> <span style="color:var(--syntax-text-color)">Simple</span> <span style="color:var(--syntax-text-color)">{</span>
    <span style="color:var(--syntax-text-color)">a</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-text-color)">i32</span><span style="color:var(--syntax-text-color)">,</span>
<span style="color:var(--syntax-text-color)">}</span>

<span style="color:var(--syntax-declaration-color)">let</span> <span style="color:var(--syntax-text-color)">s1</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">Simple</span> <span style="color:var(--syntax-text-color)">{</span> <span style="color:var(--syntax-text-color)">a</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-literal-color)">10</span> <span style="color:var(--syntax-text-color)">};</span>
<span style="color:var(--syntax-declaration-color)">let</span> <span style="color:var(--syntax-text-color)">s2</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">s1</span><span style="color:var(--syntax-text-color)">;</span> <span style="color:var(--syntax-comment-color)">// s1 is copied into s2</span>
<span style="color:var(--syntax-name-color)">println!</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"s1: {}"</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-text-color)">s1</span><span style="color:var(--syntax-text-color)">.a</span><span style="color:var(--syntax-text-color)">);</span> <span style="color:var(--syntax-comment-color)">// s1 is still usable</span>
</code></span></span>

In this example, the trait Simpleis implemented , allowing replication and still be available afterwards.Copys1s2

However, be warned: not all types will work Copy. Types that manage resources, such as Stringcustom structures that own heap data, cannot implement Copytraits. In general, if a type requires some special operation when a value is deleted, then it cannot Copy. This restriction prevents double free errors, which are a common problem in languages ​​with manual memory management.

debug features

This Debugfeature can format the output structure data, which is usually used for debugging purposes. By default, Rust does not allow printing of struct values. However, once Debugthe trait is derived, you can use a macro println!with debug format (  {:?}) to print the struct value.

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-name-color)">#[derive(Debug)]</span>
<span style="color:var(--syntax-declaration-color)">struct</span> <span style="color:var(--syntax-text-color)">Rectangle</span> <span style="color:var(--syntax-text-color)">{</span>
    <span style="color:var(--syntax-text-color)">width</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-text-color)">u32</span><span style="color:var(--syntax-text-color)">,</span>
    <span style="color:var(--syntax-text-color)">height</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-text-color)">u32</span><span style="color:var(--syntax-text-color)">,</span>
<span style="color:var(--syntax-text-color)">}</span>

<span style="color:var(--syntax-declaration-color)">let</span> <span style="color:var(--syntax-text-color)">rect</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">Rectangle</span> <span style="color:var(--syntax-text-color)">{</span> <span style="color:var(--syntax-text-color)">width</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-literal-color)">30</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-text-color)">height</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-literal-color)">50</span> <span style="color:var(--syntax-text-color)">};</span>

<span style="color:var(--syntax-name-color)">println!</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"rect is {:?}"</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-text-color)">rect</span><span style="color:var(--syntax-text-color)">);</span>
</code></span></span>

In this example, a characteristic Rectangleis derived Debug, allowing you to print out its value on standard output.

PartialEq and Eq traits

This PartialEqtrait allows comparing instances of types for equality and inequality. This Eqtrait depends on PartialEq, indicating that all comparisons are reflexive, i.e. if a == band b == c, then  a == c.

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-name-color)">#[derive(PartialEq,</span> <span style="color:var(--syntax-name-color)">Eq)]</span>
<span style="color:var(--syntax-declaration-color)">struct</span> <span style="color:var(--syntax-text-color)">Point</span> <span style="color:var(--syntax-text-color)">{</span>
    <span style="color:var(--syntax-text-color)">x</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-text-color)">i32</span><span style="color:var(--syntax-text-color)">,</span>
    <span style="color:var(--syntax-text-color)">y</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-text-color)">i32</span><span style="color:var(--syntax-text-color)">,</span>
<span style="color:var(--syntax-text-color)">}</span>

<span style="color:var(--syntax-declaration-color)">let</span> <span style="color:var(--syntax-text-color)">p1</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">Point</span> <span style="color:var(--syntax-text-color)">{</span> <span style="color:var(--syntax-text-color)">x</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-literal-color)">1</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-text-color)">y</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-literal-color)">2</span> <span style="color:var(--syntax-text-color)">};</span>
<span style="color:var(--syntax-declaration-color)">let</span> <span style="color:var(--syntax-text-color)">p2</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">Point</span> <span style="color:var(--syntax-text-color)">{</span> <span style="color:var(--syntax-text-color)">x</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-literal-color)">1</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-text-color)">y</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-literal-color)">2</span> <span style="color:var(--syntax-text-color)">};</span>

<span style="color:var(--syntax-name-color)">println!</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"Are p1 and p2 equal? {}"</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-text-color)">p1</span> <span style="color:var(--syntax-error-color)">==</span> <span style="color:var(--syntax-text-color)">p2</span><span style="color:var(--syntax-text-color)">);</span>
</code></span></span>

In this example, the and traits Pointare derived so that instances can be compared.PartialEqEqPoint

PartialOrd and Ord traits

These traits support comparison operations ( <, >, <=, >=) on type instances. PartialOrdPartial ordering is allowed, where some values ​​may not be comparable. On the other hand, Orda complete ordering between values ​​can be achieved.

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-name-color)">#[derive(PartialOrd,</span> <span style="color:var(--syntax-name-color)">Ord,</span> <span style="color:var(--syntax-name-color)">PartialEq,</span> <span style="color:var(--syntax-name-color)">Eq)]</span>
<span style="color:var(--syntax-declaration-color)">struct</span> <span style="color:var(--syntax-text-color)">Point</span> <span style="color:var(--syntax-text-color)">{</span>
    <span style="color:var(--syntax-text-color)">x</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-text-color)">i32</span><span style="color:var(--syntax-text-color)">,</span>
<span style="color:var(--syntax-text-color)">}</span>

<span style="color:var(--syntax-declaration-color)">let</span> <span style="color:var(--syntax-text-color)">p1</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">Point</span> <span style="color:var(--syntax-text-color)">{</span> <span style="color:var(--syntax-text-color)">x</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-literal-color)">1</span> <span style="color:var(--syntax-text-color)">};</span>
<span style="color:var(--syntax-declaration-color)">let</span> <span style="color:var(--syntax-text-color)">p2</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">Point</span> <span style="color:var(--syntax-text-color)">{</span> <span style="color:var(--syntax-text-color)">x</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-literal-color)">2</span> <span style="color:var(--syntax-text-color)">};</span>

<span style="color:var(--syntax-name-color)">println!</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"Is p1 less than p2? {}"</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-text-color)">p1</span> <span style="color:var(--syntax-error-color)"><</span> <span style="color:var(--syntax-text-color)">p2</span><span style="color:var(--syntax-text-color)">);</span>
</code></span></span>

In this example, the , , and features Pointare exported . This allows comparing instances.PartialOrdOrdPartialEqEqPoint

default feature

This Defaulttrait allows the creation of default values ​​for types. defaultIt provides a function that returns the default value of the type.

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-name-color)">#[derive(Default)]</span>
<span style="color:var(--syntax-declaration-color)">struct</span> <span style="color:var(--syntax-text-color)">Point</span> <span style="color:var(--syntax-text-color)">{</span>
    <span style="color:var(--syntax-text-color)">x</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-text-color)">i32</span><span style="color:var(--syntax-text-color)">,</span>
    <span style="color:var(--syntax-text-color)">y</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-text-color)">i32</span><span style="color:var(--syntax-text-color)">,</span>
<span style="color:var(--syntax-text-color)">}</span>

<span style="color:var(--syntax-declaration-color)">let</span> <span style="color:var(--syntax-text-color)">p1</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">Point</span><span style="color:var(--syntax-text-color)">::</span><span style="color:var(--syntax-name-color)">default</span><span style="color:var(--syntax-text-color)">();</span> <span style="color:var(--syntax-comment-color)">// Creates a Point with x and y set to 0</span>
</code></span></span>

In this example, features Pointare exported Default. This allows to create Pointan instance with a default value (0 in this case).

async/await and futures

futures

An A in Rust Futuremeans a value that may not yet be computed. They are a concept in concurrent programming that enable non-blocking computations: the program can continue with other tasks instead of waiting for slow computations to complete.

Futures are based on Futuretraits, and their simplest form looks like this:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-declaration-color)">pub</span> <span style="color:var(--syntax-declaration-color)">trait</span> <span style="color:var(--syntax-text-color)">Future</span> <span style="color:var(--syntax-text-color)">{</span>
    <span style="color:var(--syntax-declaration-color)">type</span> <span style="color:var(--syntax-text-color)">Output</span><span style="color:var(--syntax-text-color)">;</span>
    <span style="color:var(--syntax-declaration-color)">fn</span> <span style="color:var(--syntax-name-color)">poll</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-declaration-color)">self</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-text-color)">Pin</span><span style="color:var(--syntax-error-color)"><&</span><span style="color:var(--syntax-declaration-color)">mut</span> <span style="color:var(--syntax-declaration-color)">Self</span><span style="color:var(--syntax-error-color)">></span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-text-color)">cx</span><span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-error-color)">&</span><span style="color:var(--syntax-declaration-color)">mut</span> <span style="color:var(--syntax-text-color)">Context</span><span style="color:var(--syntax-text-color)">)</span> <span style="color:var(--syntax-declaration-color)">-></span> <span style="color:var(--syntax-text-color)">Poll</span><span style="color:var(--syntax-error-color)"><</span><span style="color:var(--syntax-declaration-color)">Self</span><span style="color:var(--syntax-text-color)">::</span><span style="color:var(--syntax-text-color)">Output</span><span style="color:var(--syntax-error-color)">></span><span style="color:var(--syntax-text-color)">;</span>
<span style="color:var(--syntax-text-color)">}</span>
</code></span></span>

This Futuretrait is the asynchronous version of Generator. It has a method that pollis called by the executor to push the future to completion. The pollmethod checks whether Futureits calculations have completed. If so, return it Poll::Ready(result). If not, it returns Poll::Pendingand arranges for the current task pollto be notified when it should be called again.

async and await

asyncAnd awaitare used in Rust for processing Futures. You can think of it as asynca way of creating Future, and awaita way of consuming Future.

asyncis a keyword that you can put in front of a function to make it return one Future. Here's a simple async function:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-declaration-color)">async</span> <span style="color:var(--syntax-declaration-color)">fn</span> <span style="color:var(--syntax-name-color)">compute</span><span style="color:var(--syntax-text-color)">()</span> <span style="color:var(--syntax-declaration-color)">-></span> <span style="color:var(--syntax-text-color)">i32</span> <span style="color:var(--syntax-text-color)">{</span>
    <span style="color:var(--syntax-literal-color)">5</span>
<span style="color:var(--syntax-text-color)">}</span>
</code></span></span>

computeIt will return a when you call it Future, and will yield a value when the driver is done 5.

awaitis a Futureway to suspend the execution of the current function until a completes. Here is an example:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-declaration-color)">async</span> <span style="color:var(--syntax-declaration-color)">fn</span> <span style="color:var(--syntax-name-color)">compute_and_double</span><span style="color:var(--syntax-text-color)">()</span> <span style="color:var(--syntax-declaration-color)">-></span> <span style="color:var(--syntax-text-color)">i32</span> <span style="color:var(--syntax-text-color)">{</span>
    <span style="color:var(--syntax-declaration-color)">let</span> <span style="color:var(--syntax-text-color)">value</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-name-color)">compute</span><span style="color:var(--syntax-text-color)">()</span><span style="color:var(--syntax-declaration-color)">.await</span><span style="color:var(--syntax-text-color)">;</span>
    <span style="color:var(--syntax-text-color)">value</span> <span style="color:var(--syntax-error-color)">*</span> <span style="color:var(--syntax-literal-color)">2</span>
<span style="color:var(--syntax-text-color)">}</span>
</code></span></span>

Here, compute().awaitexecution is paused compute_and_doubleuntil it computefinishes running. Once computecomplete, its return value is used to resume the compute_and_doublefunction.

While a function is suspended await, the executor can run other functions Futures. This is how asynchronous programming in Rust achieves high concurrency: by running multiple tasks concurrently, and switching between them while the tasks wait for slow operations such as I/O.

Executor

Executors are responsible for driving tasks Futureto completion. Describes Futurewhat needs to happen, but the Executor's job is to make it happen. In other words, without an executor, Futuresnothing can be done.

block_onHere's a simple example using the executor from the crate futures:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-declaration-color)">use</span> <span style="color:var(--syntax-text-color)">futures</span><span style="color:var(--syntax-text-color)">::</span><span style="color:var(--syntax-text-color)">executor</span><span style="color:var(--syntax-text-color)">::</span><span style="color:var(--syntax-text-color)">block_on</span><span style="color:var(--syntax-text-color)">;</span>

<span style="color:var(--syntax-declaration-color)">async</span> <span style="color:var(--syntax-declaration-color)">fn</span> <span style="color:var(--syntax-name-color)">hello</span><span style="color:var(--syntax-text-color)">()</span> <span style="color:var(--syntax-declaration-color)">-></span> <span style="color:var(--syntax-text-color)">String</span> <span style="color:var(--syntax-text-color)">{</span>
    <span style="color:var(--syntax-text-color)">String</span><span style="color:var(--syntax-text-color)">::</span><span style="color:var(--syntax-name-color)">from</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"Hello, world!"</span><span style="color:var(--syntax-text-color)">)</span>
<span style="color:var(--syntax-text-color)">}</span>

<span style="color:var(--syntax-declaration-color)">fn</span> <span style="color:var(--syntax-name-color)">main</span><span style="color:var(--syntax-text-color)">()</span> <span style="color:var(--syntax-text-color)">{</span>
    <span style="color:var(--syntax-declaration-color)">let</span> <span style="color:var(--syntax-text-color)">future</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-name-color)">hello</span><span style="color:var(--syntax-text-color)">();</span>
    <span style="color:var(--syntax-declaration-color)">let</span> <span style="color:var(--syntax-text-color)">result</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-name-color)">block_on</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-text-color)">future</span><span style="color:var(--syntax-text-color)">);</span>
    <span style="color:var(--syntax-name-color)">println!</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"{}"</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-text-color)">result</span><span style="color:var(--syntax-text-color)">);</span>
<span style="color:var(--syntax-text-color)">}</span>
</code></span></span>

In this example, block_ona is taken Futureand the current thread is blocked until a Futurecompletes. Then it returns Futurethe result.

There are many different executors available in Rust, each with different characteristics. Some, for example tokio, are designed for building high-performance web services. Others, for example async-std, provide a set of asynchronous utilities that feel like the standard library.

Remember, as the developer, it's your responsibility to ensure that Futuresthe executors push to completion properly. If a Futureis discarded without completing or driving to completion awaited, it doesn't have a chance to clean itself up.

Taken together, Rust's async/awaitsyntax and Futurefeatures provide a powerful model for writing asynchronous code. However, they are also complex and require a good understanding of the language's ownership and concurrency models.

In summary,

Rust provides a powerful toolset for complex programming tasks, providing unparalleled control over system resources. It contains high-level types, traits, and asynchronous functions, and meets both low-level and high-level programming needs. While Rust might seem intimidating at first, the benefits it offers in terms of performance, control, and safety make the learning journey worthwhile. Understanding the concepts of ownership, borrowing, and lifetime will be your guide in navigating Rust's complexities. By embracing these principles, you'll be equipped to tackle the most challenging aspects of Rust programming. Happy coding!

Guess you like

Origin blog.csdn.net/jascl/article/details/131325566