当前位置:网站首页>Gopher to rust hot eye grammar ranking

Gopher to rust hot eye grammar ranking

2022-06-12 16:19:00 sealyun

Gopher turn Rust Hot eye grammar ranking

author : Chinese chess - sealos author ,sealer Originator

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 are from golang Just turned around , You must often forget to write semicolons , about Rust In terms of language , This statement and expression based approach is very important , And many times it's convenient to have expressions ,
For example, don't write again return, Or use... When matching .

Statement performs some operations with no return value , The expression will evaluate and return a value , So semicolon ‘;’ It's important .

TOP 9 Exclamatory mark

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

What the hell is this , Why? println Add an exclamation point after it , Tell me not to print ? Actually, this is go There are no macros in it , Macros can do many things that functions can't do , It is also very convenient in many cases .
Like metaprogramming , Variable parameters , Implement a feature for the specified type, etc , And the deployment is done before compiling . Its essence is generation ( Replace ) Some codes , Let's write less code .

TOP 8 &str String::from(" Silly, distributed clearly ")

Why is the whole string so troublesome ...

let s = "hello";

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

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

s The size is unknown , Distributed on the heap , The type is String.

TOP 7 Reference borrow

A regular reference is a pointer type , Points to the memory address where the object is stored .
To borrow : Get the reference of the variable .

let x = 5;
let y = &x;

here y Namely x References to . Ownership of variables when referenced ( Monogamy ) There will be no transfer , quote =( Derailment ).

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()
}

image

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 at , Oh , This is called Attribute, Can do a lot of things , Such as :

  • Conditional compilation code
  • Set up crate name 、 Version and type ( Binary file or library )
  • Ban lint ( Warning )
  • Enable compiler features ( macro 、 Global import (glob import) etc. )
  • Link to a non Rust The library of languages
  • Mark functions as unit tests
  • Mark the function as part of the benchmark

etc. ...

After getting used to it, I found , It's a lot simpler , You can also write less good code . such as :

#[derive(Debug)] //  Add it to print the structure debug Information. , You don't have to do it yourself Display
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);

A novice who just started writing must feel like a piece of garbage , I can't understand how to get a return value , Why is it so complicated . In fact, this is a very safe design ,Tony Hoare, null The inventor of the , Once said
I call it my billion dollar mistake . at that time , I'm 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 automatic checking of the compiler . But in the design process , I failed to resist the temptation , The concept of null reference is introduced , Because it's very easy to implement . Because of this decision , Caused countless errors 、 Loopholes and system crashes , It caused billions of dollars of pain and injury over the next 40 years .

We write golang I often visit nil Object raises an error , and rust Abandoned this practice in . Automatically go to the branch of null value , It's very safe and elegant after habit .

let age = Some(30);
if let Some(age) = age { // if let You won't take out null values , 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 ?@ Operator allows one field to be bound to another variable , So you can use this variable in the following code .

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

self Most people understand every minute , But another Self, The moment other languages come over, they panic ...

It's also very simple ,Self Represents the structure itself ,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 Just to fit in superego , Is to access the parent module , It has nothing to do with it

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

TOP 2 Generic

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,
{

gopher Are you cataracted by the above code ? But I've been in contact with c++ All the possibilities are acceptable ,I,H,B In fact, it represents a type ,where It indicates that you can't be of any type ,
Must meet certain characteristics .

Generics do bring a lot of convenience in many times , Write a lot less code , The compiler will generate a lot of code for us based on generics ,Rust Many optimizations have also been made in the area of generic performance , The specific type is known at runtime , No need for dynamic distribution , This is better than slag c++ Too much ( I'm black c++ Not afraid of being scolded )

go I think the interface can meet this demand , No generics introduced , It's quite simple , Has its programming Philosophy .

TOP 1 Life cycle statement

whatever gopher The first time I saw this single quotation mark, my eyes must have been blinded , 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 return values live at least as long as 'a As long as ( Because the return value is either x, Or y), If you don't declare , Sorry to make you cry ...
So novices have a feeling of hostility to the compiler when writing , 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 ";

Extremely comfortable TOP 3

Wrote so many hot eye grammar ( In fact, it seems black and boastful ), Worry about being killed rust Powder beating , To add a few points that I feel extremely comfortable :

TOP 3 Enumeration and matching

Rust The enumeration and matching of are very strong , Very widely used , You might say we have switch case ah , And then in rust Of enum and match In front of him is a younger brother .

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 , Tuple structure, etc , It's very useful , For example, developing a communication module , There are several types of data received , It can be very convenient and elegant to solve the problem , for instance :
stay sealos use rust There is similar code in the front end written :

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

Route matching , Some routes have parameters , Some don't , It can be realized through enumeration .

TOP 2 Package management

cargo Package management is very comfortable ,gopher You should often encounter ten minutes of coding , Rely on solving a whole day's situation , This is in rust Inside , There is no the . and go The way of package management has changed many times ,
What tools should be used , Should it be vendor wait , But as the golang The upgrade of the version is much better than the earlier version .

TOP 1 Error handling

Write go Our estimates have been 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 , two if err != nil, Let's see 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)
}

? Can transparently transmit errors , And you can chain multiple calls , In this way, the code will be much simpler .Rust Error handling is more than that , The above is the most representative , hope go v2 It 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 go turn rust Students need ideas , Both languages are excellent , Which one of black doesn't exist ,gopher and
Rust Spray the powder gently ~

Programming languages have their own advantages , Let's talk about my own study Rust A little experience of :

  1. say Rust The learning curve is steep , This is actually very unfavorable to the promotion , It's not that hard , Especially for c/c++ For basic people , Absolutely nothing , Don't put any pressure on your mind .
  2. Really learn from me go python It's going to be a little different ,go python Basically take a glance and directly write the project ,Rust I think it's still necessary to study systematically .
  3. Hands on ! Hands on ! Hands on ! Say it three times , You understand the examples in the book , No matter how simple it is, you may not be able to write it yourself , If you can write it, you may not be able to compile it , So it's very important to do it .
  4. summary , Summarize some difficult things , Blogging or something , This process will make you rethink , Deeper understanding .

Information

This article cites a large number of rust Language Bible Code and introduction , Very good learning materials , Want to learn systematically rust Students can refer to

原网站

版权声明
本文为[sealyun]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202281717188338.html