Rust Programming Tips (1)

preface

Rust has been known about for some time. Rust first became known to Deno as a project written by Ryan Dahl, the father of Node.js.

Deno is a simple, modern and secure runtime for JavaScript and TypeScript that uses V8 and is built in Rust.

Then you learned about WebAssembly(WASM) : WebAssembly is a new type of code that runs in modern Web browsers and provides new performance features and effects. It is designed not to write code by hand but to provide an efficient compilation target for low-level source languages such as C, C++, and Rust.

Wait a minute for C/C++ to enter the same echelon.

No, if you come across the same thing in many places, you’ll realize it’s time to get to know it better:)

First date with Rust

There are a lot of languages or frameworks that you’ll look forward to when you first meet them. For example, the compiler doesn’t know which one to select. But Rust installs so smoothly that on a quiet afternoon, I installed Rustup on Windows and MacOS without a hitch, which made me so happy that I wanted to order a cappuccino.

Installation tutorial: doc.rust-lang.org/book/ch01-0…

Cargo

Cargo is Rust’s build system and package management tool. Similar to NPM for NodeJS, Maven for Java. Cargo also comes with tests and documentation. So this guy to get to know, and later not to deal with him. In addition, Rust’s compiler is very strict, making it a daunting task for beginners to compile. You can use Cargo C to obediently follow the compiler’s instructions:

# Analyze the current package and report errors, but don't build object files
cargo check
# or
cargo c
Copy the code

The check command analyzes whether the current project will compile, but does not build it. Check instead of build. This will speed up your development workflow. Details are as follows:

use case build performance check performance speedup
initial compile 11s 5.6 s 1.96 x
second compile (no changes) 3s 1.9 s 1.57 x
third compile with small change 5.8 s 3s 1.93 x

Table data source: doc.rust-lang.org/edition-gui…

HelloWorld!

fn main() {
  println!("Hello World!");
}
Copy the code

When you look at Rust code, you will find that Rust authors really care about their words. For example, the fn keyword is 6 characters short compared to JavaScript function, so many people choose () => {} in JS. Others simply don’t want to write the long function keyword (like me 🙃).

And public as pub, missing three characters. In Rust, external modules must declare pub when they want to use internal methods.

As you can see, the most commonly used keywords are very short. The idea is similar to the game, where the first and second positions of the inventory are filled with various items that regenerate mana.

Rust keywords:

As, break, const, continue, Crate, else, enum, extern, false, fn, for, if, impl, in, let, loop, match, mod, move, mut, pub, ref, return, self, S Elf, static, struct, super, trait, True, Type, unsafe, use, Where, while

New keywords in Edition 2018:

Async, await, dyn

In addition, some keywords that have not been used but may be used in the future have been specified to prevent damaging changes to the application caused by version updates

All reserved keywords:

Abstract, become, box, DO, final, macro, Override, PRIV, Typeof, UNSIZED, Virtual, Yield

Reserved keywords added in Edition 2018:

try

For more information: doc.rust-lang.org/reference/k…

A few keywords might be useful analogies:

  • use: similar toimport, also supports writing methods like deconstruction assignment;
  • loop: similar towhile(true)
  • trait: Similar to some programming languagesinterfaceorabstract class
  • struct: similar to C++classOr jsprototype
  • impl: similar toimplementIn fact, it is often used to givestructDeclare methods, and implement sometraitAnd so on;
  • type: similar toTypeScripttypeCannot be used as a variable name: (
  • mod: similar tonamespace;

The OwnerShip of OwnerShip

This concept is unique to Rust. Most people probably only know Pointers to memory operations, since C was born in 1972 and Rust was born in 2015. Forty-three years too late, Rust would have called C Grandpa.

Different languages have different ways of managing memory:

  • Garbage collector (GC) : While the program is running, it is constantly looking for memory that is no longer used, with the disadvantage of requiring runtime and additional performance overhead. Representative languages: Java, JavaScript, Php, C#, Go, Python, Swift
  • Manually allocate memory: for example, C passesmallocTo allocate memory and pass throughfreeRelease memory. This gives 100% control to the programmer, but who can guarantee that every memory will be allocated and freed properly? Many programs and even operating systems have many bugs caused by the abnormal use of Pointers, so there is no guarantee. Representative languages: C and C++

Rust OwnerShip is another solution to memory management. Through the powerful compiler, during compilation time through the insertion of clean code, to achieve precise cleaning, some bugs were killed in the cradle.

How to understand OwnerShip?

In my humble opinion, ownership is more intuitive.

For example, IF I go to the grocery store and buy a drink, I transfer ownership of part of my balance to the store owner by scanning the payment code, and then the store owner transfers ownership of the drink to me.

When the store owner checks the drinks I have taken, he or she will find that he or she cannot check them because I already own them and I have left the concession stand after buying the drinks.

Let’s describe this process in code:

let my_money = String::from("Three dollars.");
let my_drinks;
/* The grocery store lifecycle */ {
  let drinks = String::from("Drink");
  let shop_owner_money = my_money;
  my_drinks = drinks;
  println!("shop owner money: {}", shop_owner_money);
  println!("shop owner drinks: {}", drinks);
}
println!("my money: {}", my_money);
println!("my drinks: {}", my_drinks);
Copy the code

My_money and drinks are declared with String:: FROM. This construct is used here only to declare a variable with a lifetime of the current lifetime, so ignore this for now since this is just about ownership

Let my_money = String::from("三 元 "); -------- move occurs because `my_money` has type `String`, which does not implement the `Copy` trait let shop_owner_money = my_money; -------- value moved here println! ("my money: {}", my_money); ^^^^^^^^ value borrowed here after moveCopy the code

Here my_money has given ownership of my money to Shop_owner_money. So, when I buy a drink and try to use my money again, an error occurs.

Borrowing and variable borrowing

Borrowing can be interpreted as: I can lend you, but the ownership is still mine, you don’t mess with it!

Variable borrowing means: I can lend it to you, and you can use it.

Once you understand the basic concepts, you can understand a lot of compilation errors.

Such as:

let mut myphone = String::from("Huawei");
let temp = &myphone;
myphone.push_str(" mate 40");
println!("{}", temp);
Copy the code

Here we define a variable myphone, which is then assigned to temp as an unavailable loan. When we call myphone.push_str, there is an internal mutable borrowing that goes into the definition of push_str, as shown in the code below, where self is &mut.

pub fn push_str(&mut self, string: &str) {
  self.vec.extend_from_slice(string.as_bytes())
}
Copy the code

But there’s really no error here, what’s really wrong is the fourth println! Cargo C (“{}”, temp)

error[E0502]: cannot borrow `myphone` as mutable because it is also borrowed as immutable ... let temp = &myphone; -------- immutable borrow occurs here myphone.push_str(" mate 40"); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here println! ("{}", temp); ---- immutable borrow later used hereCopy the code

Error: Cannot borrow myphone as mutable borrow, because it is also borrowed as immutable borrow

So when we call push_str in error, the compiler looks at us and gives us an error as soon as we use temp.

I borrowed my Huawei phone for you, and then I printed it as IOS. When you use it later, you will be stupid, so it will not work. But it looks like they just changed “Huawei” to “Huawei Mate 40” and it looks harmless, even profitable? !

But how can you be sure he won’t push a “\riphone 4”? (doge

So how do we deal with it?

Mut myphone = mut myphone = mut myphone

error[E0499]: cannot borrow `myphone` as mutable more than once at a time ... let temp = &mut myphone; ------------ first mutable borrow occurs here myphone.push_str(" mate 40"); ^^^^^^^ second mutable borrow occurs here println! ("{}", temp); ---- first borrow later used hereCopy the code

Boy, it’s still an error.

According to the tip, we can clearly know that we cannot borrow more than one variable borrow at a time.

This should be easy to understand.

For example, when you were in school, you must have lent your eraser to someone else, but maybe someone else lent it to someone else, and then someone else lent it to someone else, and eventually your eraser will never see you again.

Perhaps Rust writers have known this since childhood, which is why they came up with such designs. : ^)

Results after compiler guidance:

let mut myphone = String::from("Huawei");
let temp = &mut myphone;
temp.push_str(" mate 40");
println!("{}", temp);
Copy the code

conclusion

Space is limited, so that’s all for this article.

It has to be said that with the development of The Times, many things are developing in the direction of instinctive cognition, and the concept of OwnerShip is easier to understand. (At least that’s what I think, OwnerShip hooray)

In my opinion, Rust has a great package manager and build tool Cargo, a python-like syntax, performance comparable to C/C++, a modern configuration file format, Toml, and the formation of the Rust Foundation early this year (our Huawei is a founding platinum member), And will launch edition 2021 at the end of the year, or blockchain hot language, you don’t know?

Rust is still a new language and requires a collective commitment to thrive.

The above is my personal summary of some experiences, if there are questions and corrections for my content, welcome to leave a message in the comment section.