The Detroit Post
Saturday, 16 October, 2021

Is Rust Easy

author
Christina Perez
• Monday, 14 December, 2020
• 106 min read

Languages that emphasize performance tend to be difficult to work with and easy to blow off your feet with (like C and C++). The Rust language, originally created by Gray don Hear and currently sponsored by Mozilla Research, is an attempt to do just those things.

rust techniques easy halloweenforum
(Source: www.halloweenforum.com)

Contents

(The Google Go language has similar ambitions, but Rust aims to make as few concessions to performance as possible.) Good reasons abound for creating a language where safety sits on equal footing with speed and development power.

Rust started as a Mozilla research project partly meant to reimplement key components of the Firefox browser. A few key reasons drove that decision: Firefox deserved to make better use of modern, multicore processors; and the sheer ubiquity of web browsers means they need to be safe to use.

Rust ’s memory-management system is expressed in the language’s syntax through a metaphor called ownership. The way ownership is transferred between objects is strictly governed by the compiler, so there are no surprises at runtime in the form of memory-allocation errors.

Every bit of memory in a Rust program is tracked and released automatically through the ownership metaphor. Rust ’s safeties can be partly suspended where you need to manipulate memory directly, such as referencing a raw pointer à la C/C++.

The key word is partly, because Rust ’s memory safety operations can never be completely disabled. Even then, you almost never have to take off the seatbelts for common use cases, so the end result is software that’s safer by default.

project mailbox
(Source: www.rustoleum.com)

Microsoft Windows users are not second-class citizens, either; the Rust tool chain is as capable there as it is on Linux and macOS. Few developers want to start work in a new language if they find it has fewer, or weaker, features than the ones they’re used to.

Idolize feedback in Visual Studio Code from the Rust Language Server. The Rust Language Server offers more than basic syntax checking; it also determines things like variable use.

Some of these hurdles trip up new “crustaceans” (as Rust fans call each other) and old hands alike. So, while much of the core language’s syntax and functionality has been hammered down, a great many other things around it are still fluid.

Ownership, borrowing, and Rust ’s other memory management conceits trip everyone up the first time. Many newbie Rust programmers have a common rite of passage, “fighting the borrow checker,” where they discover firsthand how meticulous the compiler is about keeping mutable and immutable things separate.

Rust is inclined to insist that the programmer spell out how to handle such things, rather than let the compiler guess. The team also has plans to make borrowing and lifetimes more flexible and easier to understand.

bed truck rusted fix easy
(Source: www.youtube.com)

But sometimes its textbooks are difficult because they are for native English speakers. This textbook is for these companies and people to learn Rust with simple English.

It's popular because it gives you the speed and control of C or C++ but also the memory safety of other newer languages like Python. That means that there are some new things to learn, and you can't just “figure it out as you go along”.

But it still looks pretty familiar if you know another language and it is made to help you write good code. I am a Canadian who lives in Korea, and I wrote Distrust while thinking of how to make it easy for companies here to start using it.

I hope that other countries that don't use English as a first language can use it too. Rust in Easy English was written from July to August 2020, and is over 400 pages long.

If you see anything wrong or have a pull request to make, go ahead. Over 20 people have already helped out by fixing typos and problems in the code, so you can too.

rust shutterbugs list
(Source: www.sudburyshutterbugs.ca)

I'm not the world's best Rust expert, so I always like to hear new ideas or see where I can make the book better. In Part 1, you will learn as much Rust as you can just in your browser.

You can actually learn almost everything you need to know without installing Rust, so Part 1 is very long. Some examples are: working with files, taking user input, graphics, and personal settings.

You can write your code there and click Run to see the results. You can run most of the samples in this book inside the Playground in your browser.

Only near the end you will see samples that go beyond what you can do in the Playground (like opening files). Release: compiles slower, runs much faster, removes debug information.

Click on Share to get an URL link. After you click share, you can click on Open a new thread in the Rust user forum to ask people there for help right away.

sew valance easy patterns idea tutorials
(Source: www.guidepatterns.com)

Tools: Custom will format your code nicely. Tools: Clippy will give you extra information about how to make your code better.

Config: here you can change your theme to dark mode so you can work at night, and many other configurations. is like "“nder construction"” it means that the code is not complete.

Those examples are correct, but need a FN main() for you to run them. And some code examples show you a problem that we will fix.

Those might have a FN main() but generate an error, and so they will have a . Comments are made for programmers to read, not the computer.

There is another kind of comment that you write with /* to start and */ to end. In this example you can see that you need to write // for every line.

toilet bowl rust stains remove before rusty
(Source: www.mymommystyle.com)

Rust has many types that let you work with numbers, characters, and so on. Some are simple, others are more complicated, and you can even create your own.

But unsigned integers can only be positive, because they do not have a sign. This means the number of bits on your type of computer.

There are many reasons for the different types of integers. One reason is computer performance: a smaller number of bytes is faster to process.

Unicode uses smaller numbers for characters that are used more, like A through Z, or digits 0 through 9, or space. This means that Rust can safely cast an u8 into a char, using as.

The easier way, however, is just to tell Rust that my_number is an u8. So those are two reasons for all the different number types in Rust.

layering holtz tim stencil gears stencils anonymous rust stamper stn st heart imagination own ranger rusty finnabair dried attached once
(Source: janhobbins.blogspot.com)

Here is another reason: size is the size that Rust uses for indexing. So Rust uses size so that your computer can get the biggest number for indexing that it can read.

A char needs to be 4 bytes so that it can hold any kind of character. You can see that an is one byte, the German ß is two, the Japanese is three, and the ancient Egyptian is 4 bytes.

.chars().count() turns what you wrote into characters and then counts how many there are. Actually, usually you don't need to tell it.

That is because the compiler chooses i32 for integers if you don't tell it. To specify a type, add a colon after the variable name.

But some variables can't, and you need to debug print. Debug sometimes doesn't look pretty, because it has extra information to help you.

rust
(Source: www.youtube.com)

But prints with different formatting over more lines. If you want to see the smallest and biggest numbers, you can use MIN and MAX.

Std means “standard library” and has all the main functions etc. But in the meantime, you can remember that this is how you get the smallest and largest number for a type.

When you declare a variable with let, it is immutable (cannot be changed). The compiler says: error: cannot assign twice to immutable variable my_number.

And because they are in the same scope block (the same {}), we can't see the first my_number anymore. Shadowing is good when you need to change a variable a lot.

In general, you see shadowing in Rust in this case. It happens where you want to quickly take variable, do something to it, and do something else again.

lights string metallic spray project outdoor rustoleum painted final craft decor
(Source: spraypaint.rustoleum.com)

The stack, the heap, and pointers are very important in Rust. The stack and the heap are two places to keep memory in computers.

It's not super slow either, but the stack is always faster. So simple variables like i32 go on the stack, because we know their exact size.

So then the computer first goes to the stack, reads the pointer, and follows it to the heap where the data is. Pointers sound complicated, but they are easy.

The pointer you usually see in Rust is called a reference. This is the important part to know: a reference points to the memory of another value.

A reference means you borrow the value, but you don't own it. It's the same as our book: the table of contents doesn't own the information.

blinds outdoor roller windows porches patios ambient exterior range installed za
(Source: www.blindsandshuttersdirect.co.za)

Sometimes you have too many and escape characters, and want Rust to ignore everything. This prints the same thing, but using r# makes it easier for humans to read.

So with r# you can avoid mistakes with variable names that were not keywords before. Or maybe for some reason you really need a function to have a name like return.

If you want to print the bytes of a STR or a char, you can just write b before the string. A hexadecimal number goes inside the {} to print it.

Here is a short example of how to get the Unicode number, and how to print it again. For example, if you have a reference, you can use {:p} to print the pointer address.

Pointer address means the location in your computer's memory. It might be different every time, depending on where your computer stores it.

(Source: git.ir)

Or you can add numbers to change the order. Maybe you have a very complex string to print with too many variables inside the {} curly brackets.

Or maybe you need to print a variable more than one time. For example, 55 with three “padding zeros” looks like 00055.

That's because of the reason we saw above: the stack needs to know the size. Let's look at the reason for using a & for STR s again to make sure we understand.

For example, the names “” and “Adrian Fahrenheit Types” are not the same size: If we wrote STR, Rust wouldn't know what to do because it doesn't know the size.

There are two types that don't use let to declare: coast and static. These are for variables that don't change (coast means constant).

(Source: rustcraft.ru)

Rust uses references to make sure that all memory access is safe. But the String country only lives inside the function, and then it dies.

Once a variable is gone, the computer will clean up the memory and use it for something else. Rust prevents us from making a mistake with memory here.

This is the important part about the “owned” type that we talked about above. Rust has two rules for mutable and immutable references.

They are very important, but also easy to remember because they make sense. Rule 1 : If you have only immutable references, you can have as many as you want.

This is because mutable references can change the data. You could get problems if you change the data when other references are reading it.

acid sulfuric boiling fuming concentrating
(Source: www.amazingrust.com)

A good way to understand is to think of a PowerPoint presentation. Situation one: An employee is writing a PowerPoint presentation.

The employee gives his login information to his manager, and asks him to help by making edits. Now the manager has a “mutable reference” to the employee's presentation.

The manager can make any changes he wants, and give the computer back later. Situation two: The employee is giving the presentation to 100 people.

All 100 people can now see the employee's data. They all have an “immutable reference” to the employee's presentation.

This is fine, because they can see it but nobody can change the data. Situation three: The Employee gives his manager his login information.

fall wedding centerpieces centerpiece vibrant flowers roses branches orange fun leaves
(Source: www.deerpearlflowers.com)

Now the 100 people have to watch the manager write an email to his mother instead of the presentation. The compiler prints a helpful message to show us the problem.

It works because the compiler is smart enough to understand our code. Earlier in Rust this kind of code actually generated an error, but the compiler is smarter now.

Now let's do something similar with a mutable reference. Here is an example of a function that uses a mutable variable.

If it doesn't return anything, then the variable dies inside the function. Here is an example that looks like a mutable reference, but it is different.

The moment you call adds_hungary, it becomes the full owner. Country has nothing to do with String::from(“Austria”) anymore.

winter wall decor diy decorations snowflake rustic crafts thaw frozen etsy
(Source: www.flairflickers.com)

In this situation it is like the employee just giving his whole computer to the manager. The employee won't ever touch it again, so the manager can do anything he wants to it.

These simple types are all on the stack, and the compiler knows their size. These simple types include: integers, floats, Boolean (true and false), and char.

But if you look at the documentation for String, it is not copy type. On the left in Trait Implementations you can look in alphabetical order.

Clone is similar to Copy, but usually needs more memory. In this example, prints_country() prints the country name, a String.

But in the documentation we saw that String implements the Clone trait. Of course, if the String is very large,.clone() can use a lot of memory.

broom power water pressure sweeper yard washer tools hose washing garden lawn homeowner wash leaf pool unique cool needs every
(Source: odditymall.com)

But you can't use it yet, and Rust won't compile if anything is uninitialized. You have a code block and the value for your variable is inside it, and The variable needs to live outside the code block.

You can see that my_number was declared in the main() function, so it lives until the end. And if you wrote let my_number = loop_then_return(number) inside the block, it would just die right away.

Loop_then_return(number) gives the result 100, so let's delete it and write 100 instead. Rust has a lot of types for making a collection.

Collections are for when you need more than one value in one spot. For example, you could have information on all the cities in your country inside one variable.

Here is a good tip: to know the type of variable, you can “ask” the compiler by giving it bad instructions. So it tells you method not found in ``, which is the type.

stairs exterior stair roof outdoor diy kits basement deck stringers loft attic fast standing build steel storage attaching kit prefabricated
(Source: www.fast-stairs.com)

Then we can change zero to other numbers in order to add data. You can also have an inclusive range, which means it includes the last number too.

You can see that a DEC always has something else inside it, and that's what the <> (angle brackets) are for. Say for example you wanted to save your favorite book as a DEC.

Because a DEC is slower than an array, we can use some methods to make it faster. A DEC has a capacity, which means the space given to the vector.

We'll use a method called.capacity() to look at the capacity of a vector as we add items to it. So if you think you know how many elements you need, you can use DEC::with_capacity() to make it faster.

You can use a tuple to create multiple variables. There are many more collection types, and many more ways to use arrays, vets, and tuples.

Control flow means telling your code what to do in different situations. == is to compare, = is to assign (to give a value).

This prints It's a different number because it's not equal to 7 or 6. This prints It's a positive odd number because when you divide it by 2 you have a remainder of 1, and it's greater than 0.

Write the pattern on the left and use a fat arrow to say what to do when it matches. Put a comma between the arms (not a semicolon).

That is because, after the match is over, we actually told the compiler this: let second_number = 10; This prints Its dark but not bad because it matches “cloudy” and “warm” for sky and temperature.

In this match on colors, we have three but only check one at a time. This also shows how match statements work, because in the first example it only printed Not much blue.

You can also use @ to give a name to the value of a match expression, and then you can use it. In this example we match an i32 input in a function.

You will use structs all the time in Rust because they are so convenient. The name of a struct should be in UpperCamelCase (capital letter for each word, no spaces).

If you write a struct in all lowercase, the compiler will tell you. For a unit struct, you just write the name and a semicolon.

It is “unnamed” because you only need to write the types, not the field names. This prints The second part of the color is: 0.

In this struct you declare field names and types inside a {} code block. Note that you don't write a semicolon after a named struct, because there is a whole code block after it.

But it is not very important either way so you can choose whether to use a comma or not. Let's create a Country struct to give an example.

The Country struct has the fields' population, capital, and leader_name. They look very similar to a struct, but are different.

Note: it's the same key as * for referencing but is completely different. Parts of an ENIM can also be turned into an integer.

But if you don't, Rust will just add 1 from the arm before to give it a number. But you can actually use an ENIM to put different types in.

The compiler doesn't care that we have either u32 or i32 because they are all inside a single type called Number. With loops, you can tell Rust to continue something until you want it to stop.

The program compiles fine, but Rust will remind you that you didn't use number : Putting _ in front of a variable name means “maybe I will use it later”.

So you can put _ in front of variable names if you will use them later and don't want the compiler to tell you about them. Here is an example with a loop and a break that gives my_number its value.

And because the whole block starts with let, my_number gets the value. Now that we know how to use loops, here is a better solution to our match problem with colors from before.

It is a better solution because we want to compare everything, and a for loop looks at every item. This is where you can start to give your structs and ends some real power.

Regular methods: these take self (or self or smut self). You usually see associated methods used to create new variables.

If you write # above the struct or ENIM then you can print it with {:?} You can sometimes use them to tell the compiler to give your struct an ability like Debug.

But derive is probably the most common and you see it a lot above structs and ends. Remember that Self (the type Self) and self (the variable self) are abbreviations.

You can get the values from a struct or ENIM by using let backwards. We learned that this is restructuring, because you get variables that are not part of a structure.

This prints: They call him Father Doc but his real name is Clarence. First we say let father_doc = Person {fields} to create the struct.

In the function we just create a DEC, but you can imagine that we can do much more after we restructure it. This prints The city's two names are .

In functions, you write what type to take as input: Usually, generics uses types with one capital letter (T, U, V, etc.

We have to write out each type name, and think about how we want to use it. We want to print them too, so we require Display for U as well.

Rust sees that the function wants something impossible, and stops. We can get the value inside an option with.unwrap(), but be careful with.unwrap().

If you unwrap a value that is None, the program will panic. The message is: “thread 'main' panicked at 'called Option::unwrap() on a None value', src\main.rs:14:9”.

In this code, we will use a method called .is_some() to tell us if it is Some. In this easier way, we don't need handle_option() anymore.

This is true: we only returned the Result but it could have been an Err. Remember, the four methods to easily check are .is_some(), is_none(), is_ok(), and is_err().

Sometimes a function with Result will use a String for the Err value. Src\main.rs:30:20 means “inside main.rs in directory src, on line 30 and column 20”.

Result functions in the standard library and other people's code usually do this. This function takes a vector of bytes (u8) and tries to make a String.

For example, the .get() method returns an Option on a DEC. Let's use a range from 0 to 10 to see if it matches the numbers in my_vec.

A Yashmak is a collection made out of keys and values. Actually they are very similar to each other, so we can quickly change our Yashmak to a Freeman to see.

You can get a value in a Yashmak by just putting the key in square brackets. In this next example we will bring up the value for the key Bielefeld, which is Germany.

But be careful, because the program will crash if there is no key. If it exists it will be Some(value), and if not you will get None instead of crashing the program.

This prints Some(“L\'Charlemagne Modern”) because there was already a key for 1, so we didn't insert Le Petite Prince. Yashmak has a very interesting method called.entry() that you definitely want to try out.

With it, you can try to make an entry and use another method like .or_insert() to insert the value if there is no key. The interesting part is that it also gives a mutable reference so you can change it if you want.

Let's pretend that we have a library and want to keep track of our books. Maybe it would be better to count the number of books so that we know that there are two copies of Eye of the World.

.entry() actually returns an ENIM called Entry : Then when we call .or_insert(), it looks at the ENIM and decides what to do.

The important part is let return_value = book_hash map.entry(book).or_insert(0);. Without let, it does nothing: it inserts 0, and nobody takes the mutable reference to 0.

Then we increase the value by 1, which gives at least 1 for every book in the Yashmak. Then when.entry() looks at Eye of the World again it doesn't insert anything, but it gives us a mutable 1.

Let's pretend that we asked men and women on the street what they think of a politician. Then we want to put the numbers together to see if the politician is more popular with men or women.

If not, it will insert a DEC::new(), then push the number in. If it sees “female” already in the Yashmak, it will not insert a new DEC, and will just push the number into it.

A hash set implemented as a Yashmak where the value is (). If you put them into a Hash Set then you will have a list of all the numbers that appeared.

If we print each item in the Hash Set, we don't know what the order will be: Here as well, it is easy to change your Hash Set to a Street if you decide you need ordering.

In our code, we only need to make two changes to switch from a Hash Set to a Street. A BinaryHeap is an interesting collection type, because it is mostly unordered but has a bit of order.

We will use another list of items for an example, but this time smaller. You can see that the number in the 0 index is always largest: 25, 20, 15, 10, 5, then 0.

A good way to use a BinaryHeap is for a collection of things to do. Here we create a BinaryHeap<(u8, STR)> where the u8 is a number for the importance of the task.

A Vendée is a DEC that is good at popping items both off the front and the back. When you use .pop() on a DEC, it just takes off the last item on the right and nothing else is moved.

But if you take it off another part, all the items to the right are moved over one position to the left. Imagine a big parking lot where every time one car leaves all the cars on the right side have to move over.

This, for example, is a lot of work for the computer. In fact, if you run it on the Playground it will probably just give up because it's too much work.

It is usually a bit slower than a DEC, but if you have to do things on both ends then it is much faster. It is now much faster, and on the Playground it finishes in under a second instead of giving up.

Then we make a Vendée and use .push_front() to put them at the front, so the first item we added will be on the right. We use our done() function to pop an item off the back, but we don't want to delete it.

We will write a function called parse_str that tries to turn a STR into an i32. That means “check if it is an error, and give what is inside the Result if it is okay”.

We need to wrap it in Ok because the return is Result, not i32. One easy way is to “ask” the compiler again.

But here is a useless but quick example that shows how you can use it on a single line. This prints the same thing, but this time we handled three Result s in a single line.

Later on we will do this with files, because they always return Result s because many things can go wrong. Imagine the following: you want to open a file, write to it, and close it.

For example, this function called prints_three_things always prints index , , and from a vector. But imagine that later on we write more and more code, and forget that my_vec can only be three things.

() : if the part inside () is not true, the program will panic. These messages will only display if the program panics.

And it displays our message that says You entered Mithridates. Unwrap is also good when you are writing your program and you want it to crash when there is a problem.

Later, when your code is finished it is good to change unwrap to something else that won't crash. You can also use expect, which is like unwrap but a bit better because you give it your own message.

Textbooks usually give this advice: “If you use.unwrap() a lot, at least use.expect() for better error messages.” The error message is thread 'main' panicked at 'called Option::unwrap() on a None value', src\main.rs:7:18.

It crashes again, but the error is better: thread 'main' panicked at 'Input vector needs at least 4 items', src\main.rs:7:18. Now here is an example of a bad practice, a function that tries to unwrap two times.

It takes a DEC>, so maybe each part will have a Some or maybe a None. The message is: thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', src\main.rs:2:32.

Maybe not good if you want the program to panic if there's a problem. But usually we don't want our program to panic, so unwrap_or is a good method to use.

Because Debug and the others are so common, we have attributes that automatically do it. But other traits are more difficult, so you need to implement them manually with imply.

But Rust doesn't know exactly how you want to add things, so you have to tell it. The important thing to remember about trait s is that they are about behavior.

This is okay, but we don't want to print “The dog is running”. You can change the methods that a trait gives you if you want, but you have to have the same signature.

If you think the user will use it differently, then just write the function signature. So let's try implementing the Display trait for our struct.

Now when we use {} to print, we get Reggie Mantle is a cat who is 4 years old. By the way, if you implement Display then you get the String trait for free.

Macro for the .FMT() function, which lets you make a String with .to_string(). The thing to remember about traits is that they are about the behavior of something.

If you think of some traits we've seen so far, they are all about behavior: Copy is something that a type can do. String is another trait, and it's also something that a type can do: it can change into a String.

Let's look at another example that is even more connected to just behavior. We'll imagine a fantasy game with some simple characters.

One is called FightClose, and lets you fight up close. We pass self inside our trait all the time, but we can't do much with it right now.

It could be a Wizard, it could be a Ranger, it could be a new struct called Toefocfgetobjtnode or anything else. In a real game it might be better to rewrite this for each type, because You are now at: Wizard {health: 60} looks funny.

That's also why methods inside traits are usually simple, because you don't know what type is going to use it. Let's rewrite our code with something similar but different.

So you can see there are many ways to do the same thing when you use traits. It all depends on what makes the most sense for the program that you are writing.

Now let's look at how to implement some main traits you will use in Rust. If you look at the type, the second and third vectors are DEC, which means the bytes of the STR and the String.

You can see that From is easy to implement from types you didn't create like DEC, i32, and so on. You can try to make the example generic if you want for practice.

You can see that it takes self and gives a reference to the other type. This means that if you have a generic type T, you can say that it needs AMREF.

Rust says error: T doesn't implement std::FMT::Display. Don't forget that you can use where to write the function differently when it gets long.

If we add Debug then it becomes FN print_it + Display + Debug>(input: T) which is long for one line. Rust is a systems programming language like C and C++, and its code can be written as separate commands in separate lines, but it also has a functional style.

With functional style you can chain methods. You can use this functional style best when you understand closures and iterators.

This method lets you do something to every item, then pass it on. Inside each method we can give a name to every item (we just called it x) and use that to change it.

These are called closures, and we will learn about them in the next section. Vector1 is still alive because we only used references: we didn't take by value.

It is mutable, so we don't need to use.collect() to create a new DEC. Instead, we change the values in the same DEC with mutable references.

An iterator works by using a method called .next(), which gives an Option. Implementing Iterator for your own struct or ENIM is not too hard.

First let's make a book library and think about it. Now we want to implement Iterator for the library, so we can use it in a for loop.

On the top left of the page it says: Associated Types: Item and Required Methods: next. You can see that under imply Iterator for Alternate it says type Item = i32.

Our iterator will be for our list of books, which is a DEC. To implement Iterator, you need to write the FN next() function.

Closures are like quick functions that don't need a name. They are very common in Rust, and once you learn to use them you will wonder how you lived without them.

When the closure becomes more complicated, you can add a code block. You didn't need to put anything in || because it can just take number_one and number_two and add them.

By the way, that is where the name closure comes from, because they take variables and “enclose” them inside. But people will often call all || functions closures, so you don't have to worry about the name.

We will just say “closure” for anything with a ||, but remember that it can mean an “anonymous function”. They feel “high level”, so sometimes people think that the machine code will be complicated.

But the machine code that Rust makes from it is just as fast as a regular function. In that section we wrote |x| to bring in the next item in an iterator, and that was a closure.

Here is another example: the unwrap_or method that we know that you can use to give a value if unwrap doesn't work. You don't always need to use a {} and write complicated code just because there is a closure.

The.enumerate() method gives an iterator with the index number and the item. Actually, this is the interesting thing about iterators.

If you try to map without a method like collect, the compiler will tell you that it doesn't do anything. It won't panic, but the compiler will tell you that you didn't do anything.

This is a warning, so it's not an error: the program runs fine. So this Map>> is a structure that is ready to go, but only when we tell it what to do.

Rust only wants to do one calculation, so it creates the structure and waits. This is what iterators are lazy and do nothing unless consumed means.

You can even create complicated things like Yashmak using.collect(), so it is very powerful. Here is an example of how to put two vets into a Yashmak.

This method takes two iterators and attaches them together, like a zipper. Let's pretend we have a big string that made of 3-digit numbers.

This means that the closure needs an argument (like x), but you don't want to use it. So |_| means “Okay, this closure takes an argument but I won't give it a name because I don't care about it”.

Rust becomes a very fun to language once you become comfortable with closures. With closures, you can chain methods to each other and do a lot of things with very little code.

Let's filter the months of the year. Each company has a name so that field is String, but the CEO might have recently quit.

No problem: there is a method called .ok() that turns Result into Option. It is called .ok() because all it can send is the Ok result (the Err information is gone).

Using.parse() is an easy example for this, where we try to parse some user input. It returns a Result, but we are using filter_map() so we just throw out the errors.

Also, you can see now that the else part in the names of these methods means that it has a closure. We can take our Option from the Company struct and turn it into a Result this way.

But for now we just give it an error message, so it becomes a Result. And if you don't, pass on “No CEO found” inside Err.

Now let's use .ok_or_else() so we can use a closure and get a better error message. To create a String, and put the company name in that.

.and_then() is a helpful message that takes an Option, then lets you do something to its value and pass it on. It is sort of like a safe “unwrap, then do something, then wrap again”.

An easy example is a number that we get from a DEC using .get(), because that returns an Option. First here is a built example to help imagine.

In this example we make a very large DEC (about 20,000 items) with all the characters from 'a' to ''. Then we make a function to check if a character is inside it.

Next we make a smaller DEC and ask it whether it is all alphabetic (with the .is_alphabetic() method). By the way, .any() only checks until it finds one matching item, and then it stops.

It won't check them all if it has already found a match. If you are going to use .any() on a DEC, it might be a good idea to push the items that might match near the front.

Let's pretend that we want to use .any() to see if it contains 5. Remember, an Iterator always has .next() that lets you check what it does every time.

This prints Final counter is: 1001, so we know that it had to call .next() 1001 times before it found 5. .find() is different from .any() because it returns an Option with the value inside (or None).

With.cycle() you can create an iterator that loops forever. So even though.cycle() might never end, the other iterator only runs six times when zipping them together.

That means that the iterator made by.cycle() doesn't get a .next() call again so it is done after six times. Both print ten characters, but the second one skipped 1300 places and prints ten letters in Armenian.

In .fold(), you first add a starting value (if you are adding items together, then 0), then a comma, then the closure. First here is a simple example showing .fold() to add items together.

On step 1 it starts with 0 and adds the next number: 9. Here is an example where we add a '-' to every character to make a String.

.take_while() which takes into an iterator as long as it gets true (take while x > 5 for example).cloned() which makes a clone inside the iterator. .chunks() and.windows() are two ways of cutting up a vector into a size you want.

Let's say you have a vector with 10 items, and you want a size of 3. So it will try to make a slice of three items, but if it doesn't have three then it won't panic.

.match_indices() lets you pull out everything inside a String or STR that matches your input, and gives you the index too. It is similar to.enumerate() because it returns a tuple with two items.

.peekable() lets you make an iterator where you can see (peek at) the next item. It's like calling .next() (it gives an Option) except that the iterator doesn't move, so you can use it as many times as you want.

You can actually think of peekable as “stoppable”, because you can stop for as long as you want. In this example we put names into a struct depending on the number of spaces in the STR.

It gives you the iterator item and you can print it or do whatever you want. String literals: you make these when you write let my_STR = “I am a STR”.

They last for the whole program, because they are written directly into the binary. If you create a String and get a reference to it, Rust will convert it to a STR when you need it.

This is because references can't live longer than the object they come from. That's because we returned a STR with a lifetime of static.

So now FN returns_STR() &'static STR tells Rust : “don't worry, we will only return a string literal”. String literals live for the whole program, so Rust is happy.

We are just telling the compiler what the lifetimes of the inputs will be. Actually, every variable has a lifetime, but usually we don't have to write it.

The compiler is pretty smart and can usually figure out for itself. Imagine we want to create a City struct and give it a STR for the name.

However, note that we can only take “string literals”, so not references to something else. This is important to understand, because the reference we gave it actually lives long enough.

But we promised that we would only give it a &'static STR, and that is the problem. It said to try writing struct City<'a> and name: &'a STR.

This means that it will only take a reference for name if it lives as long as City. One good tip is that changing the lifetime to a “human-readable” name can help you read code if it is very complicated.

Let's look at the comparison to traits for generics again. It means “please only take an input for name if it lives at least as long as City “.

It does not mean: “I will make the input for name live as long as City “. This is called the “anonymous lifetime” and is an indicator that references are being used.

Rust will suggest it to you when you are implementing structs, for example. So we did what we needed to do for the struct : first we said that name comes from a STR.

That means we need a lifetime, so we gave it <'a>. Then we had to do the same for the struct to show that they are at least as long as this lifetime.

Much of the time, when the compiler wants a lifetime you will just end up writing <'a> here and there and then it will work. It's just a way of saying “don't worry, I won't give you anything that doesn't live long enough”.

The compiler will start to complain, but also give some suggestions. First we'll go back and take the lifetimes out, and also implement Display.

Display will just print the Adventurer's name. Now it's happy with those parts, but is wondering about the imply blocks.

So you can see that lifetimes are often just the compiler wanting to make sure. And it is usually smart enough to almost guess at what lifetimes you want, and just needs you to tell it so it can be certain.

Remember how in Rust you need to use but to change a variable? There are also some ways to change them without the word but.

This is because Rust has some ways to let you safely change values inside a struct that is immutable. Each one of them follows some rules that make sure that changing the values is still safe.

It is better for the fields in Phoneme to be immutable, because we don't want the data to change. A phone model will first be on sale (true), but later the company will stop selling it.

Cell has a method called .set() where you can change the value. Cell works for all types, but works best for simple Copy types because it gives values, not references.

Cell has a method called get() for example that only works on Copy types. A Recall is another way to change values without needing to declare but.

But you have to be careful with a Recall, because it checks borrows at runtime, not compilation time. Runtime means when the program is actually running (after compilation).

Already borrowed: BorrowMutError is the important part. So when you use a Recall, it is good to compile and run to check.

Mute is another way to change values without declaring but. This is why a Mute is safe, because it only lets one process change it at a time.

“Go out of scope” means the code block is finished. If you don't want to use a different {} code block, you can use std::me::drop(mutex_changer).

You have to be careful with a Mute because if another variable tries to lock it, it will wait: Also, you don't need to make a variable to change the Mute.

The program will run forever if you try to.write() when you can't get access: It means “clone on write” and lets you return a STR if you don't need a String, and a String if you need it.

That is why we need a & for a STR, because the compiler doesn't know the size. So if you want a trait that can use something like a STR, you add ? Sized.

Imagine that you have a function that returns Cow<'static, STR>. We will put a number into a function that returns a Cow<'static, STR>.

Depending on the number, it will create a STR or a String. Cow has some other methods like into_owned or into_borrowed so you can change it if you need to.

Usually you use them when you have a very long type and don't want to write it every time. It is also good when you want to give a type a better name that is easy to remember.

Note that this doesn't create an actual new type. But we saw that you can do this anywhere, especially in functions with ends that have long names.

So now we will import Misdirection inside the function. That means that inside the function you can just write North and so on.

In our case, that means North, Northeast ...and all the way to Northwest. A lot of times you see a section called prelude in other people's code with all the main items you probably need.

Sometimes you want to write code in general to help you imagine your project. For example, imagine a simple project to do something with books.

If you add that to the function, Rust will not complain, and will compile. So now the code compiles and you can see the result of check_book_type : It's hardcover.

These are some reasons for RC, which lets you have more than one owner. Then once the number of owners goes down to 0, the variable can disappear.

Of course, it doesn't work because canada_cities now owns the data and Calgary doesn't. To add a new reference, you have to clone the RC.

It's like putting a name sticker on a box of books to show that two people own it, instead of making a whole new box. We can check the number of owners with RC::strong_count(item).

Weak pointers are useful because if two RC s point at each other, they can't die. Also, you use RC::weak_count(item) to see the weak count.

If you use multiple threads, you can do many things at the same time. Modern computers have more than one core, so they can do more than one thing at the same time, and Rust lets you use them.

(Some other languages use “green threads”, which are less powerful) You create threads with std::thread::spawn and then a closure to tell it what to do.

Threads are interesting because they run at the same time, and you can test it to see what happens. Usually about four threads will print before main ends, but it is always different.

String is not Copy, so my_closure() is FN : it takes a reference. It is a long message, but helpful: it says to use the `move` keyword.

You can make your own functions that take closures, but inside them it is less free and you have to decide the type. Outside a function a closure can decide by itself between FN, Input and Nonce, but inside you have to choose one.

The best way to understand is to look at a few function signatures. A closure is always generic because every time it is a different type.

F: F is usually what you see for a closure: this is the variable name and the type. Next is the part about the closure: F: Input(Self::Item) built.

Here it decides that the closure is Input, so it can change the values. It changes the values of Self::Item, which is the iterator that it takes.

We will create a DEC and then iterate over it just to show what we can do now. For a more real example, we will create a City struct again.

This time the City struct has more data about years and populations. When we use .city_data(), it gives us the years and the populations and a closure, so we can do what we want with the data.

The closure type is FnMut, so we can change the data. This will print the result of all the times we called .city_data().

Impl Trait is similar to generics. You remember that generics use a type T (or any other name) which then gets decided when the program compiles.

Remember, this means “only take types that already have Partial and Display “. Now let's look at imply Trait, which is similar.

Then it will take in a type that implements that trait. However, the more interesting part is that we can return imply Trait, and that lets us return closures because their function signatures are traits.

Fn map(self, f: F) mean that it takes two generic types. It must be an Input, and do the closure on Self::Item, which is the iterator that you give it.

Here is a small example of a function that gives you a closure depending on the number you put in. If you put 2 or 40 in then it multiplies it, and otherwise it gives you the same number.

Because it's a closure we can do anything we want, so we also print a message. Let's imagine a game where your character is facing monsters that are stronger at night.

We can make an ENIM called Timeously to keep track of the day. Your character is named Simon and has a number called character_fear, which is a f64.

We will make a change_fear function that changes his fear, but also does other things like write messages. You remember that we used a RC to give a variable more than one owner.

Atomic means that it uses the computer's processor so that data only gets written once each time. This is important because if two threads write data at the same time, you will get the wrong result.

An Arc uses the processor to make sure this doesn't happen, so it is the method you must use when you have threads. You don't want an Arc for just one thread though, because RC is a bit faster.

So let's use a Mute inside an Arc to change the value of a number. You can see that the threads are working at the same time.

This is called concurrency, which means “running together”. Now that we have safe clones attached to my_number, we can move them into other threads with no problem.

Then we can join the two threads together in a single for loop, and make the code smaller. We need to save the handles, so we can call .join() on each one outside the loop.

If we do this inside the loop, it will wait for the first thread to finish before starting the new one. Finally, this prints Mute {data: 20} .

These looks complicated but Arc>> is used very often in Rust, so it becomes natural. A channel is an easy way to use many threads that send to one place.

They are fairly popular because they are pretty simple to put together. You can create a channel in Rust with std::sync::MSC.

Mpsc means “multiple producer, single consumer”, so “many threads sending to one place”. This creates a Sender and a Receiver that are tied together.

So you have to choose one name for the sender and one for the receiver. Usually you see something like let (sender, receiver) = channel(); to start.

Because it's generic, Rust won't know the type if that is all you write: It suggests adding a type for the Sender and Receiver.

Once you start using the Sender and Receiver, Rust can guess the type. So let's look at the simplest way to use a channel.

So you can use.unwrap() to see if the sending works, or use better error handling. Let's make two threads and send values to receiver.

The two threads start sending, and then we print! Now let's pretend that we have a lot of work to do, and want to use threads.

We will create a new DEC and use.extend() to put the work in. It's important to know how to read documentation in Rust so you can understand what other people wrote.

Now you can see that a String is a kind of DEC. And actually a String is a vector of u8 bytes, which is interesting to know.

You didn't need to know that to use the with_capacity method so you only see it if you click . So clicking on is a good idea if the document doesn't have much detail and you want to know more.

The important part of the documentation for a trait is “Required Methods” on the left. For example, for Iterator you need to write the .next() method.

These attributes are small pieces of code that give information to the compiler. If you write an attribute with just # then it will affect the code on the next line.

Of course, dealing with dead code and unused variables is important. Or you might need to show some code or teach people Rust and don't want to confuse them with compiler messages.

This works with many common traits that can be automatically derived. But for traits that you can automatically derive, you can put in as many as you like.

Let's give HoldsAString seven traits in a single line, just for fun, even though it only needs one. # means configuration and tells the compiler whether to run code or not.

You see it usually like this: #. Then you can have tests next to your code but the compiler won't run them unless you tell it to.

With that you can tell the compiler to only run the code on Windows, or Linux, or anything else. is an interesting attribute that tells Rust not to bring in the standard library.

That means you don't have DEC, String, and anything else in the standard library. You will see this in code for small devices that don't have much memory or space.

When you use a Box, you can put a type on the heap instead of the stack. At first, it is hard to imagine where to use it, but you use it in Rust a lot.

Even without data it is a bit complicated, and Rust does not use this type of pattern very much. This is because Rust has strict rules on borrowing and ownership, as you know.

This only takes something with Display, so it can't accept our struct DoesntImplementDisplay. You can use a Box because otherwise the compiler won't know the size of the value.

This example shows that a trait can be used on something of any size: Dyn is a word that shows you that you are talking about a trait, not a struct or anything else.

We can quickly create two error types to show this. To make an official error type, you have to implement std::error::Error for it.

That part is easy : just write imply std::error::Error {}. But errors also need Debug and Display, so they can give information on the problem.

If we didn't have a Box and wrote this, we would have a problem: This is not surprising, because we know that a trait can work on many things, and they each have different sizes.

You can implement the Default trait to give values to a struct or ENIM that you think will be most common. The builder pattern works nicely with this to let users easily make changes when they want.

Actually, most general types in Rust already have Default. They are not surprising: 0, “" (empty strings), false, etc.

It has a new function which we used to make a character named Billy with some stats. But maybe in our world we want most of the characters to be named Billy, age 15, height 170, weight 70, and alive.

The builder pattern lets us chain very small methods to change one value each time. That's because.height() has full ownership and nobody else can touch it, so it is safe to be mutable.

When you give a user a method like.height() you can make sure that they only put in an u32(), but what if they enter 5000 for height? We will use a final method called.build() that returns a Result.

Inside it, we will check if the user input is okay, and if it is, we will return an Ok(Self). We don't want users to be free to create any kind of character anymore.

So we'll move the values from imply Default to .new(). This prints the same thing: Character {name: “Bobby”, age: 15, height: 180, weight: 60, life state: Alive} .

We are almost ready to write the method.build(), but there is one problem: how do we make the user use it? But we will add a can_use: built value to Character.

Only.build() will set it to true again, so now the user has to do a final check with.build(). Also, in our game there is a bad word called smurf that we don't want characters to use.

It makes the whole String lowercase (small letters), and checks for.contains() instead of ==. If everything is okay, we set can_use to true, and give the character to the user inside Ok.

Now let's imagine a simple type that just holds a number. It will be like a Box, and we have some ideas for some extra functions for it.

The message cannot be referenced gives us a clue: we need to implement Dark. Something simple that implements Dark is sometimes called a “smart pointer”.

A smart pointer can point to its item, has information about it, and can use its methods. Because right now we can add my_number.0, which is an u8, but we can't do much else with a HoldsANumber : all it has so far is Debug.

Interesting fact: String is actually a smart pointer to STR and DEC is a smart pointer to array (or other types). The.checked_sub() method is a safe subtraction that returns an Option.

Remember, an u8 can't be negative so it's safer to do.checked_sub() so we don't panic. We can also implement DerefMut, so we can change the values through *.

This is also why the standard library says: Dark should only be implemented for smart pointers to avoid confusion. That's because you can do some strange things with Dark for a complicated type.

A new Character needs some stats like intelligence and strength. Now let's imagine that we want to keep character hit points in a big DEC.

Maybe our code is 2000 lines long, and suddenly we have to figure out why we are .push() ING *billy. Of course, it is not illegal to write hit_points_DEC.push(*billy), but it makes the code look very strange.

Probably a simple .get_hp() method would be much better, or another struct that holds the characters. Dark gives a lot of power but it's good to make sure that the code is logical.

Inside the file you write you can also make a mod. You can see that we wrote use std::FMT::Display; inside print_things, because it is a separate space.

If you wrote use std::FMT::Display; inside main() it wouldn't help. Without the pub keyword in front of FN it will stay private.

These makes sense because traits are about giving the same behavior to something. So let's put a struct named Billy inside print_things.

But the user can select the number of times to print, so that will be public. By the way, the * to import everything is called the “glob operator”.

You can think of the structure like this: even if you are in a country, you might not be in a province. You probably noticed that crate::country::province::print_province(province); is very long.

When we are inside a module we can use super to bring in items from above. Actually the word super itself means “above”, like in “superior”.

In our example we only used the function once, but if you use it more than it is a good idea to import. It can also be a good idea if it makes your code easier to read, even if you only use the function once.

Testing is a good subject to learn now that we understand modules. But if you try to run it in the Playground, it gives an error: error: `main` function not found in crate `playground.

(left, right) is the main way to test a function in Rust. If it doesn't work, it will show the different values: left has 2, but right has 3.

This is a setting on your computer to give a lot more information about errors. Luckily the Playground has it too: click on ··· next to STABLE and set backtrack to enable.

So let's turn backtrack off again and return to regular tests. Usually you will want to put your tests in their own module.

Also don't forget to write use super::*; because the test module needs to use the functions above it. You might see the words “test-driven development” when reading about Rust or another language.

It's one way to write programs, and some people like it while others prefer something else. Then you start writing the code, and run the tests to see if you did it right.

Then the tests are always there to show you if something goes wrong when you add to and rewrite your code. This is pretty easy in Rust because the compiler gives a lot of information about what to fix.

Let's write a small example of test-driven development and see what it looks like. Let's imagine a calculator that takes user input.

You can also see that function names in tests are usually quite long. We'll imagine that a single function called math() will do everything.

And all the information about thread 'tests::one_plus_one_is_two' panicked at 'assertion failed: `(left == right)`. So let's start with a coast that contains all the values.

To do that, add # attribute: now if it panics the test will succeed. Our math() function will only accept good input now.

This is the interesting part about having tests first: the actual code starts much later. + doesn't need to be an input, but when the program sees + it should know that the number is done.

For example, the input 11+1 should do something like this: 1) See 1, push it into an empty string. This is easy with .trim_end_matches(), where you remove anything that matches at the end of a STR.

Refactor means to make code better, usually through things like structs and ends and methods. You can see that there is a back and forth process in test-driven development.

If you change your code later on and run the tests, if one of them doesn't work you will know what to fix. One good way to start is with Clippy.

If you installed Rust then you can type cargo Clippy, and if you're using the Playground then click on TOOLS and select Clippy. Clippy will look at your code and give you tips to make it simpler.

And a for loop is actually an iterator, so we don't have any reason to write .inter(). Instead of separate variables, we will create a Calculator struct.

Now our code is actually a bit longer, but easier to read. For example, if adds is now if calculator.adds, which is exactly like reading English.

We could write more methods but lines like calculator.results.push(calculator.current_input.clone()); are already very clear. You don't want to just refactor to make the code short: CLC.CLR() is much worse than calculator.clear(), for example.

For this section you almost need to install Rust, but we can still use just the Playground. Now we are going to learn how to import crates that other people have written.

It is very easy to import other crates, and The Rust standard library is quite small. That means that it is normal in Rust to bring in an external crate for a lot of basic functions.

The idea is that if it is easy to use external crates, then you can choose the best one. To begin learning external crates, we will start with the most common one: rand.

In any case, it's very easy to bring in a crate. If you have Rust on your computer, there is a file called Cargo.Tom that has this information.

And when you click on that, you can see a screen that says Cargo.Tom rand = “0.7.3”. To get to the documents you can click on the docs button in the page on crates.Io.

It will print a different u16 number every time, like 42266 52873 56528 46927 6867. And actually if you look at random it says: “This is simply a shortcut for thread_rng().gen() “.

With random numbers we can do fun things like make characters for a game. Each character rolls a d6 three times, so each stat is between 3 and 18.

We will make this method too so the owner of the game can decide. We created a Character struct for the stats, and even implemented Display to print it the way we want.

The character with four dice is usually a bit better at most things. Rayon is a popular crate that lets you speed up your Rust code.

This is still very fast in Rust, but if you want you can make it faster with Rayon. Rayon has many other methods to customize what you want to do, but at its most simple it is just “add _par to make your program faster”.

Serde is a popular crate that lets you convert to and from formats like JSON, YAML, etc. The most common way to use it is by creating a struct with two attributes on top.

The Serialize and Deserialize traits are what make the conversion easy. (That's also where the name serve comes from) If you have them on your struct, then you can just call a method to turn it into and from JSON or anything else.

The regex crate lets you search through text using regular expressions. Regular expressions are a whole other language have to learn that too if you want to use them.

Chrono is the main crate for people who need more functionality for time. We will look at the standard library now which has functions for time, but if you need more than this is a good crate to use.

Now that you know a lot of Rust, you will be able to understand most things inside the standard library. Let's take a look at some parts in it that we haven't learned yet.

This tour will go over most parts of the standard library that you don't need to install Rust for. We will revisit a lot of items we already know, so we can learn them with greater understanding.

If you want to get variables from an array, you can put their names inside to restructure it. This is the same as using a tuple in match statements or to get variables from a struct.

You can use the.escape_unicode() method to get the Unicode number for a char : You can get a char from u8 using the Form trait, but for an u32 you use From because it might not work.

Also, as of late August 2020 you can now get a String from a char. These are good methods if you think you might get a number that won't fit into a type.

They return an Option so you can safely check that your math works without making the program panic. You'll notice that on the page for integers it says RHS a lot.

This is not a keyword, but you will see it a lot of so it's good to know. While we are on the subject, let's learn how to implement Add.

Let's imagine that we want to add two countries together, so we can compare their economies. Later on in this code we could change .FMT() to display a number that is easier to read.

The three others are called Sub, Mud, and Div, and they are basically the same to implement. For +=, -=, *= and /=, just add Assign : Addressing, Unassign, Unassign, and DivAs sign.

F32 and f64 have a very large number of methods that you use when doing math. F32 and f64 have a method called .max() and .min() that gives you the higher or the lower of two numbers.

Here is a way to use this with .fold() to get the highest or lowest number. In Rust, you can turn a built into an integer if you want, because it's safe to do that.

DEC has a lot of methods that we haven't looked at yet. But there is one more interesting way to sort called .sort_unstable(), and it is usually faster.

Our String is very large, and we don't want to add anything more to it, so we can make it a bit smaller. When we did that, Rust saw that we needed more space and gave us double: now it's 7000000.

It has types like String and String, which are like String for the operating system or String for the language C. They each have their own STR type too: USSR and CSR. Ffi means “foreign function interface”.

You can use String when you have to work with an operating system that doesn't have Unicode. All Rust strings are Unicode, but not every operating system has it.

Here is the simple English explanation from the standard library on why we have String : A string on Windows might be made of random 16-bit values that don't have zeros.

In Rust, strings are always valid UTF-8, which may contain zeros. It also has an interesting method called .into_string() that tries to make it into a regular String.

It returns a Result, but the Err part is just the original String : You can't call.unwrap() because it will panic, but you can use match to get the String back.

Swap() : with this you can change the values between two variables. This is helpful when you have two things you want to switch and Rust doesn't let you because of borrowing rules.

One function called .take() is like.replace() but it leaves the default value in the item. You will remember that default values are usually things like 0, “", and so on.

And as you can see, it replaced all the numbers with 0: no index was deleted. Of course, for your own type you can implement Default to whatever you want.

Let's look at an example where we have a Bank and a Robber. Every time he robs the Bank, he gets the money at the desk.

But the desk can take money from the back any time, so it always has 50. The standard library has a prelude too, which is why you don't have to write things like use std::DEC::DEC to create a DEC.

Std::marker::{Copy, Send, Sized, Sync, Unpin}. You haven't seen Unpin before, because it is used for almost every type (like Sized, which is also very common).

To “pin” means to not let something move. In this case a Pin means that it can't move in memory, but most items have Unpinned so you can.

You saw this before a bit with Cow, which can take borrowed content and make it owned. You can also use .to_owned() on a STR to get a String, and the same for other borrowed values.

The simplest function is just getting the system time with Instant::now(). If you look at 2738771 seconds for example (written in August), it is 31.70 days.

But the page on Instant tells us that it isn't supposed to be useful on its own. If you look at the traits on the left, one of them is Sub.

So it takes an Instant and uses.duration_since() to give a Duration. There is one fun thing we can do with just a single Instant though.

The function is called bad_random_number because it's not a very good random number generator. Rust has better crates that make random numbers with less code than rand like fa strand.

But it's a good example of how you can use your imagination to do something with Instant. When you have a thread, you can use std::thread::sleep to make it stop for a while.

You usually use.sleep() when you have many threads that need to try something a lot, like connecting. So then you can set a Duration, and it will try to do its task every time it wakes up.

Maybe you have a match in an ENIM that you know will never choose one of the arms, so the code can never be reached. For example, let's say you have a program that writes something when you choose a place to live in.

Your program doesn't let anyone choose Chernobyl, because it's not a good place to live right now. But the ENIM was made a long time ago in someone else's code, and you can't change it.

You can imagine a big Rust program over many mods and files. But maybe you just want to change one tiny bit of code depending on the operating system, etc.

Here is an example of a function that runs differently when you use it inside a test. Now it will run differently depending on the configuration.

And because the test always returns 5 in this case, it will pass. Writing macros is interesting because they are almost a different language.

Inside is sort of like a match statement. But it's not the same as a match statement, because a macro actually doesn't compile anything.

Other Articles You Might Be Interested In

01: 360 Ventures Real Estate Albuquerque Nm
02: Jeep How Much Rust
03: Jeffrey Samuels Real Estate Honolulu
04: Jeff Boone Real Estate Tulsa
05: Jeff Chandler Real Estate
06: Jems Real Estate Anchorage
07: Jennifer Real Estate Agent Virginia Beach
08: Jennings Real Estate Group Charlotte Nc
09: Jenni Cully Real Estate Stockton Mo
10: Jeremy Irvine Real Estate
Sources
1 www.facebook.com - https://www.facebook.com/BrokerJeremy
2 jeremycampbellrealestate.com - https://jeremycampbellrealestate.com/homes-for-sale-details/275-RADIAL-IRVINE-CA-92618/OC21002099/306/
3 www.mylife.com - https://www.mylife.com/jeremy-backlin/e23331663150
4 www.countryliving.com - https://www.countryliving.com/life/news/a43306/property-brothers-naked/
5 grangehillgold.wordpress.com - https://grangehillgold.wordpress.com/interviews/jeremy-irvine-s6-7/
6 www.bostonherald.com - https://www.bostonherald.com/2020/01/24/standout-cast-makes-vietnam-war-saga-last-full-measure-worth-seeing/
7 www.sbs.com.au - https://www.sbs.com.au/movies/article/2020/09/25/movies-leaving-sbs-demand-october