Gopher to Rust hot eye grammar ranking

Gopher to Rust hot eye grammar ranking

Author: Zhongyi - sealos author, sealer initiator

TOP 10 often forget to write semicolons

fn add_with_extra(x: i32, y: i32) -> i32 {
    let x = x + 1; // sentence
    let y = y + 5; // sentence
    x + y // expression
}

When you first turn from golang, you must often forget to write semicolons. For Rust language, this method based on statements and expressions is very important, and expressions are very convenient,
For example, there is no need to write return, or use it when matching.

Statement performs some operations without return value. The expression will return a value after evaluation, so the semicolon ';' It's important.

TOP 9 exclamation point

fn main() {
   println!("hello world"); 
}

What the hell is this? Why should an exclamation point be added after println? Is it to tell me not to print? In fact, this is a macro not in go. Macros can do many things that functions can't do. In many cases, they are also very convenient.
For example, metaprogramming, variable parameters, implementing a feature for a specified type, etc., and it is ready to be expanded before compilation. Its essence is to generate (replace) some code, let's write less code.

Top 8 & STR string:: from

Why is the whole string so troublesome...

let s = "hello";

s is hard coded into the program. The size is fixed in the memory allocation of the stack area. The type is & str

let s = String::from("hello");
s.push_str(",world!");

The size of s is unknown. It is allocated on the heap and the type is String

TOP 7 reference borrowing

A regular reference is a pointer type that points to the memory address where the object is stored.
Borrowing: get a reference to a variable.

let x = 5;
let y = &x;

Here y is a reference to x. When referencing, the ownership of variables (monogamy) will not be transferred, and the reference = (cheating).

fn main() {
    let s1 = String::from("hello");

    let len = calculate_length(&s1);

    println!("The length of '{}' is {}.", s1, len);
}

fn calculate_length(s: &String) -> usize {
    s.len()
}

TOP 6 Attribute

#[allow(dead_code)]
fn unused_function() {}

This eye is really hot. Why do you want a script language comment? Take a closer look. Oh, it's called Attribute. It can do many things, such as:

  • Conditional compilation code
  • Set the name, version, and type (binary or library) of the crite
  • Disable lint (warning)
  • Enable compiler features (macros, global import, etc.)
  • Link to a library of non Rust languages
  • Mark functions as unit tests
  • Mark a function as part of a benchmark

Wait

After getting used to it, I found that it is really much simpler and less good code can be written. For example:

#[derive(Debug)] / / you can print the structure debug information by adding it. You don't need to implement the Display by yourself
struct Point {
    x: i32,
    y: i32,
}

println!("{:?}", p);

TOP 5 Option Result enumeration

fn plus_one(x: Option<i32>) -> Option<i32> {
    match x {
        None => None,
        Some(i) => Some(i + 1),
    }
}

let five = Some(5);
let six = plus_one(five);
let none = plus_one(None);

Novices who just started writing must think they are garbage. They can't understand how to get a return value. Why is the whole process so complicated. In fact, this is a very safe design. Tony Hoare, the inventor of null, once said
I call it my billion dollar mistake. At that time, I was using an object-oriented language to design the first comprehensive reference oriented type system. My goal is to ensure that the use of all references should be absolutely safe through the automatic check of the compiler. However, in the design process, I failed to resist the temptation to introduce the concept of empty reference because it is very easy to implement. It was because of this decision that countless errors, vulnerabilities and system crashes were triggered, causing billions of dollars of pain and harm in the next 40 years.

We often cause errors when we write golang because we access nil objects, which is abandoned in t rust. It is very safe and elegant to automatically go to the branch of null value after getting used to it.

let age = Some(30);
if let Some(age) = age { // if let will not take out null values, which is very comfortable
    println!("age{}",age);
}

TOP 4 variable binding@

enum Message {
    Hello { id: i32 },
}

let msg = Message::Hello { id: 5 };

match msg {
    Message::Hello { id: id_variable @ 3..=7 } => {
        println!("Found an id in range: {}", id_variable)
    },
}

id_variable @ 3..=7 gopher: is this writing code or sending a circle of friends@ You can bind another variable in the following code

TOP 3 self Self super? ID? superego? Is this a programming language or a philosophy

Self most people understand it every minute, but another self comes out, and the moment other languages come over, they panic...

In fact, it is also very simple. Self represents the structure itself, and self represents the object itself:

pub struct Rectangle {
    width: u32,
    height: u32,
}

impl Rectangle {
    pub fn new(width: u32, height: u32) -> Self {
        Rectangle { width, height }
    }
    pub fn width(&self) -> u32 {
        return self.width;
    }
}

fn main() {
    let rect1 = Rectangle::new(30, 50);

    println!("{}", rect1.width());
}

So here Self = Rectangle

super is just to cooperate with the superego, that is, to access the parent module, which has nothing to do with the above

mod a {
    pub fn foo() {}
}
mod b {
    pub fn foo() {
        super::a::foo(); // Parent module
    }
}

TOP 2 generics

fn bench_heap_sizes<I, H, B>(c: &mut Criterion, name: &str, init: I, new_test_heap: H)
where
    I: Fn(Key, &[u32]),
    H: Fn(Key, Vec<u32>) -> NewHeap,
    B: Benchmark,
{

Are gopher s cataracted by the above code? But those who have been in contact with c + + may be acceptable. I, h and B actually represent a type. where indicates that you can't have any type,
Certain characteristics must be met.

Generics do bring a lot of convenience in many times, and a lot of code is written less. The compiler will generate a lot of code for us according to generics. Rust has also made a lot of optimization in the performance of generics. It knows the specific type at runtime and does not need dynamic distribution. This is much better than slag c + + (I'm not afraid of being scolded for my black c + +)

go thinks that the interface can meet this requirement without introducing generics. It is also very simple. It has its programming philosophy.

TOP 1 life cycle statement

Any gopher must have been blinded when he first saw the single quotation mark, and then 10000 grass mud horses...

fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
    if x.len() > y.len() {
        x
    } else {
        y
    }
}

x. Y and the return value live at least as long as' a '(because the return value is either X or y). If you don't declare it, I'm sorry the compiler makes you cry...
So when novices write, they feel like they have a grudge against the compiler, and then the compiler tells you like your mother: "I'm doing it for you!"

You think it's over? And the static life cycle...

let s: &'static str = "Obsessive compulsive disorder";

Extreme comfort TOP 3

After writing so many hot eye grammars (in fact, it seems black boast), I'm worried about being beaten by rust powder to add a few points that I feel extremely comfortable:

TOP 3 enumeration and matching

Rust's enumeration and matching are very strong and widely used. You might say that we also have a switch case, and then we are a brother in front of rust's enum and match

enum Message {
    Quit,
    Move { x: i32, y: i32 },
    Write(String),
    ChangeColor(i32, i32, i32),
}

fn main() {
    let msg = Message::ChangeColor(0, 160, 255);

    match msg {
        Message::Quit => {
            println!("The Quit variant has no data to destructure.")
        }
        Message::Move { x, y } => {
            println!(
                "Move in the x direction {} and in the y direction {}",
                x,
                y
            );
        }
        Message::Write(text) => println!("Text message: {}", text),
        Message::ChangeColor(r, g, b) => {
            println!(
                "Change the color to red {}, green {}, and blue {}",
                r,
                g,
                b
            )
        }
    }
}

Enumeration can support different types and tuple structures, which is very useful. For example, when developing a communication module, there will be several types of data received, which can be very convenient and elegant to solve problems. For example:
There is similar code in the front end written by sealos in t rust:

#[derive(Switch,Clone)]
pub enum AppRoute {
    #[to = "/images/{name}"]
    ImageDetail(String),
    #[to = "/images"]
    Images
}

Route matching, some routes with parameters and some without parameters, can be realized through enumeration.

TOP 2 package management

cargo's package management is very comfortable. Gophers should often code for ten minutes and rely on it to solve the whole day. This does not exist in t rust. Moreover, the package management mode of go has changed many times,
What tools should be used, whether the vendor should be used, etc. However, with the upgrading of the golang version, this is much better than the early stage.

TOP 1 error handling

The estimates of go are written by if err= Nil torture crazy, two-thirds of the code is if err= Nil, let's feel that there is no harm without comparison:

Golang:

func read_username_from_file() (string, error) {
   f,err := os.OpenFile("hello.txt",os.O_CREATE|os.O_RDWR|os.O_APPEND, os.ModeAppend|os.ModePerm)
   if err != nil {
      return "", error
   }
   defer file.Close()
   content, err := ioutil.ReadAll(file)
   if err != nil {
      return "",error
   }
   return string(content),nil
}

Here we return the error to the upper layer for processing, twice if err= Nil, take a look at Rust:

fn read_username_from_file() -> Result<String, io::Error> {
    let mut s = String::new();
    File::open("hello.txt")?.read_to_string(&mut s)?;
    Ok(s)
}

? The error can be transmitted transparently, and multiple calls can be made in the chain, so the code will be much simpler. Rust error handling is more than that. The above is the most representative. I hope go v2 can also make error handling more convenient.

summary

The above non authoritative ranking has a very strong personal color. You don't have to be too serious. The main purpose is to circle some points that go to t rust students need ideas. Both languages are excellent. Which one does not exist? gopher and
Rust powder is sprayed lightly~

Programming languages have their own advantages. Here is my experience in learning Rust:

  1. The steep learning curve of Rust is actually very unfavorable to the promotion. In fact, it is not very difficult. Especially for people based on c/c + +, it is absolutely nothing. Don't have any pressure in your heart.
  2. It's really a little different from learning go python. Go Python basically takes a glance at the handwriting project directly. Rust, I think it's still necessary to study it systematically.
  3. Do it! Do it! Do it! Say it three times. You understand the examples in the book. No matter how simple you are, you may not be able to write it yourself, and you may not be able to compile it in the past, so it is very important to do it.
  4. Summarize, summarize some difficult things, write a blog or something. This process will make you rethink and understand more deeply.

data

A large number of references are cited in this paper T rust language Bible Code and introduction, very good learning materials, students who want to systematically learn t rust can refer to

Keywords: Go Docker Kubernetes Container Rust

Added by N1CK3RS0N on Mon, 28 Feb 2022 11:32:54 +0200