Skip to content

sinhgithub/rust-learning

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Rust Document

Author: VÕ TRƯỜNG SINH
Theme: Dark Mode

I. Variable

  • Mặc định của biến trong Rust là bất biến (immutable).
    fn main() {
        let mut x = 10; // mut = mutable
        println!("X = {}", x);
        x = 20;
        println!("X = {}", x);

        const HANG_SO: u128 = 100_000_000_000_000;
        println!("HANG_SO = {}", HANG_SO);
    }

II. Shadowing

    fn main() {
        // Shadowing
        let x : u128 = 10;
        println!("x: {}", x);
        let x: &str = "Hello";
        println!("x: {}", x);
    }

III. Data type

1. Scalar data (kiểu vô hướng)

  • Integer
    Length Signed Unsigned
    8-Bit i8 u8
    16-Bit i16 u16
    32-Bit i32 u32
    64-Bit i64 u64
    128-Bit i128 u128
    arch isize usize
    fn main() {
        let a: i32 = 111_111; // decimal;
        let b: i32 = 0o52; // octal;
        let c: i32 = 0x2A; // hexadecimal;
        let d: i32 = 0b1101_1011; // binary;
        let e: u8 = b'A'; // byte;
        println!("a: {}, b: {}, c: {}, d: {} , e: {} ", a, b, c, d, e);
    }
  • Float
    fn main() {
        let a: f64 = 1.1;
        let b: f32 = 2.0;
        println!("a + b = {}", a + b as f64);
    }
  • Boolean
    fn main() {
        let a: bool = false;
        let b = true;
        print!("{} {}", a, b);
    }
  • Character
    fn main() {
        let a = 'a';
        let b = 'a';
        let icon = '🚀';
        print!("{} {} {}", a, b, icon);
    }

2. Compound data (kiểu tổng hợp)

  • Tuple : là 1 dạng dữ liệu kết hợp với nhiều kiểu dữ liệu trong 1 Tuple
    fn main() {
        let tup = ("hello world", 42, 3.14);
        print!("tup: {:?}", tup);
        print!("tup1: {}", tup.0);
        print!("tup1: {}", tup.1);
        print!("tup1: {}", tup.2);
    }
  • Array: Là một danh sách có kích thước cố định và các kiểu dữ liệu trong đó đồng nhất 1 kiểu dữ liệu
    fn main() {
        let array = [1, 2, 3, 4, 5];
        let number = array[0];
        println!("{}", number);

        let hashing: [i32; 32] = [0; 32];
        let number1 = hashing[0];
        println!("Number 1: {}", number1);
        println!("{:?}", hashing);
        for i in hashing.iter() {
            print!("{:?}", i);
        }
    }

Ownership

|----------------------+----------------------------+-----------------------------------------------------|
|                      | Pros                       | Cons                                                |
|----------------------|----------------------------|-----------------------------------------------------|
| **Bộ thu gom rác**   | Không có lỗi               | Không thể quản lý bộ nhớ                            |
| (Garbage Collection) | Giảm thời gian viết code   | Thời gian biên dịch và chạy chương trình chậm hơn   |
|                      |                            | Dung lượng file lớn hơn                             |
|----------------------+----------------------------+-----------------------------------------------------|
| **Quản lý thủ công** | Có quyền kiểm soát bộ nhớ  | Lỗi quá trời                                        |
|                      | Chương trình chạy nhanh hơn| Viết code lâu hơn                                   |
|                      | Dung lượng file nhỏ hơn    |                                                     |
|----------------------+----------------------------+-----------------------------------------------------|
| **Ownership Model**  | Có thể kiểm soát bộ nhớ    | Viết code lâu                                       |
|                      | Không có lỗi               | Cách học và viết code hơi khác                      |
|                      | Chương trình chạy nhanh hơn|                                                     |
|                      | Dung lượng file nhỏ hơn    |                                                     |
|----------------------+----------------------------+-----------------------------------------------------|

I. Stack & heap

  1. Mỗi giá trị trong Rust chỉ có 1 biến được gọi là chủ sở hữu (one variable on owner).
  2. Chỉ có 1 owner tại một thời điểm (cho nên 1 biến không thể có 2 owner tại một thời điểm).
  3. Khi owner đi ra khỏi phạm vi hoạt động thì value sẽ bị drop
    fn main() {
    fn _x() {
        let _s = "Hello, World!";
        let _n = 5;
    }

    fn _y() {
        let mut _s: String = String::from("Hello, World!");
        let _n = 5;

        _s.push_str(" 2");

        print!("{}", _s);
    }
    _y();
}

I. Ownership

    fn main() {
        let s1: String = String::from("Hello world");
        let s2 = s1;
        //println!("{}", s1); // error: use of moved value: `s1`
        print!("{}\n", s2); // hello

        // ownership and functions
        let s = String::from("hello");
        take_ownership(s);
        // println!("{}", s); // error: use of moved value: `s`

        let received = give_ownership();
        println!("{}", received); // hello
    }

    fn take_ownership(s: String) {
        println!("{}", s);
    }

    fn give_ownership() -> String {
        let s = String::from("hello");
        s
    }

II. Reference

    fn main() {
        let mut s1: String = "hello".to_string();
        let length = length_count(&mut s1);
        print!("{}", length);
    }

    fn length_count(s: &mut String) -> usize {
        s.push_str(" world");
        let len = s.len();
        len
    }
  • Bạn chỉ có thể có 1 tham chiếu mutable cho 1 data cụ thê trong 1 phạm vi cụ thể
  • Bạn không thể tham chiếu mut nếu 1 tham chiếu immutable đã tồn tại trong 1 phạm vi
    fn main() {
        let mut s1: String = "hello".to_string();
        let s2 = &mut s1;
        //let s3 = &mut s1; // error[E0499]: cannot borrow `s1` as mutable more than once at a time
        println!("{}", s2);
        // println!("{}", s3);

        ok_main();
    }

    fn ok_main() {
        let s1: String = "hello".to_string();
        let s2 = &s1;
        let s3 = &s1;
        println!("{}", s2);
        println!("{}", s3);
    }

Cách sử dụng #Structs trong #RUST

    struct Member {
        name: String,
        email: String,
        age: u8,
        active: bool,
    }
    fn main() {
        let mut member1: Member = Member {
            name: String::from("Sinh Vo"),
            email: String::from("sinhvotctv@gmail.com"),
            age: 20,
            active: true,
        };

        member1.active = false;

        println!("{}", member1.active);

        let member2 = create_member("Giang Võ".to_string(), "giang@gmail.com".to_string(), 28);
        println!("{}", member2.name);

        let member3 = Member {
            name: "Josh".to_string(),
            ..member2
        };

        print!("{}", member3.email);
    }

    fn create_member(name: String, email: String, age: u8) -> Member {
        Member {
            name,
            email,
            age,
            active: true,
        }
    }
    fn main() {
        let width = 30;
        let height = 50;
        // Tính diện tích hình chữ nhật
        // 1.
        let area = width * height;

        println!("1. Diện tích hình chữ nhật là: {}", area);

        // 2.
        let area2 = get_area(width, height);
        println!("2. Diện tích hình chữ nhật là: {}", area2);

        // 3.
        struct Rectangle {
            width: i32,
            height: i32,
        }

        impl Rectangle {
            fn area(&self) -> i32 {
                self.width * self.height
            }
        }

        impl Rectangle {
            fn square(size: i32) -> Rectangle {
                Rectangle {
                    width: size,
                    height: size,
                }
            }
        }

        let rect = Rectangle { width, height };
        println!("3. Diện tích hình chữ nhật là: {}", rect.area());

        // 4.
        let rect2 = Rectangle::square(width);
        println!("4. Diện tích hình vuông là: {}", rect2.area());
    }

    fn get_area(width: i32, height: i32) -> i32 {
        width * height
    }

Cách sử dụng #Enum, Option Enum & Match

1. Enum

    #[derive(Debug)]
    enum IPAddressKind {
        V4,
        V6,
    }
    #[derive(Debug)]
    struct IPAddress {
        kind: IPAddressKind,
        address: String,
    }

    #[derive(Debug)]
    enum IPAddressKind2 {
        V4(String),
        V6,
    }

    #[derive(Debug)]
    enum IPAddressKind3 {
        V4(u8, u8, u8, u8),
        V6,
    }

    fn main() {
        let localhost: IPAddress = IPAddress {
            kind: IPAddressKind::V4,
            address: String::from("127.0.0.1"),
        };

        let localhost2: IPAddressKind2 = IPAddressKind2::V4(String::from("127.0.0.1"));

        let localhost3: IPAddressKind3 = IPAddressKind3::V4(127, 0, 0, 1);

        println!("1. localhost 1 {:#?}", localhost);

        println!("2. localhost 2  {:#?}", localhost2);

        println!("3. localhost 3  {:#?}", localhost3);

        // option enum
        let some_number: Option<i32> = Some(5);
        let some_string = Some("a string");
        let absent_number: Option<String> = None;
        let x = 6;
        // let sum = x + absent_number; // can not add i32 and Option<String>
        let sum = x + some_number.unwrap_or(1);

        println!("sum: {}", sum);
    }

2. Match

    #[derive(Debug)]
    enum Balance {
        Small,
        Large,
        Shark,
        Whale,
    }

    enum Coin {
        Solana,
        Bitcoin,
        Ethereum,
        Pi(Balance),
    }

    fn main() {
        fn decimals(coin: Coin) {
            match coin {
                Coin::Solana => {
                    println!("Solana");
                    1;
                }
                Coin::Bitcoin => {
                    println!("Bitcoin");
                    10;
                }
                Coin::Ethereum => {
                    println!("Ethereum");
                    18;
                }
                Coin::Pi(bala) => {
                    println!("Ethereum ==> I'm a {:#?} ", bala);
                }
            }
        }

        decimals(Coin::Solana);
        decimals(Coin::Bitcoin);
        decimals(Coin::Ethereum);
        decimals(Coin::Pi(Balance::Shark));

        // practice
        let x = Some(5);

        match x {
            Some(5) => println!("Five"),
            _ => println!("None"),
        }

        if let Some(7) = x {
            println!("Five");
        } else {
            println!("None");
        }
    }

Cách sử dụng Vectors, String, và HashMap

    use std::collections::HashMap;
fn main() {
    let vector1: Vec<i32> = vec![1, 2, 3];
    let mut vector2 = Vec::new();
    vector2.push(1);

    println!("vector 1: {:?}", vector1);
    println!("vector 2: {:?}", vector2);

    for i in &vector1 {
        println!("{}", i);
    }

    let mut i = 0;
    while i < vector1.len() {
        println!("{}", i);
        i += 1;
    }

    let str1 = String::from("Hello");
    let str2 = " world".to_string();
    let str3 = str1 + &str2;
    println!("{}", str3);

    // Hash map

    let mu: String = String::from("Mauritius");
    let uk: String = String::from("United Kingdom");

    let mut countries = HashMap::new();

    countries.insert("MU", mu);
    countries.insert("UK", uk);

    let country = countries.get("MU");
    match country {
        Some(c) => println!("{}", c),
        None => println!("Country not found"),
    }
}

Generic Types

use std::collections::HashMap;
fn main() {
    struct Point<T, U> {
        x: T,
        y: U,
    }

    impl<T, U> Point<T, U> {
        fn mixup<V, W>(self, other: Point<V, W>) -> Point<T, W> {
            Point {
                x: self.x,
                y: other.y,
            }
        }
    }

    fn main() {
        let p1 = Point { x: 5, y: 10.4 };
        let p2 = Point { x: "Hello", y: 'c' };

        let p3 = p1.mixup(p2);

        println!("p3.x = {}, p3.y = {}", p3.x, p3.y);
    }
}

Traits in Rust

    #[derive(Debug)]
    struct Data {
        num1: i32,
        num2: i32,
        str1: String,
        option: Option<i32>,
    }
    impl Data {
        fn new(num1: i32, num2: i32, str1: String, option: Option<i32>) -> Self {
            Data {
                num1,
                num2,
                str1,
                option,
            }
        }
    }

    trait Transform {
        fn transform(&self) -> String;
    }

    impl Transform for Data {
        fn transform(&self) -> String {
            format!(
                "{} {} {} {:?}",
                self.num1, self.num2, self.str1, self.option
            )
        }
    }

    fn main() {
        let a = Data {
            num1: 1,
            num2: 2,
            str1: "Hello".to_string(),
            option: Some(3),
        };

        let b = Data::new(3, 4, "Hello 23".to_string(), Some(4));

        println!("{:?}", a);
        println!("{:?}", b);
        b.transform();
    }

#LifeTime - #Rust

  • Cả tham số và giá trị trả về là tham chiếu thì mới được dùng life time
    fn main() {
        let num1 = 10;
        let num2 = 20;
        let result = get_ref(&num1, &num2);
        println!("The result is: {}", result);
    }

    fn get_ref<'a>(num1: &'a i32, num2: &'a i32) -> &'a i32 {
        if num1 > num2 { num1 } else { num2 }
    }

Error Handle & Result

    enum Position {
        IT,
        CTO,
        CEO,
        Manager,
        Marketer,
    }

    enum Status {
        Active,
        Denied,
    }
    struct Employee {
        status: Status,
        position: Position,
    }

    fn try_access(em: &Employee) -> Result<(), String> {
        match em.status {
            Status::Denied => return Err("Access Denied".to_string()),
            _ => (),
        }
        match em.position {
            Position::CEO => Ok(()),
            Position::CTO => Ok(()),
            Position::Manager => Ok(()),
            _ => Err("You are not CEO".to_string()),
        }
    }
    fn main() {
        let a = Employee {
            status: Status::Active,
            position: Position::CEO,
        };
        let b = Employee {
            status: Status::Denied,
            position: Position::Manager,
        };
        let c = Employee {
            status: Status::Active,
            position: Position::Marketer,
        };
        let d = Employee {
            status: Status::Active,
            position: Position::CTO,
        };
        let e = Employee {
            status: Status::Active,
            position: Position::IT,
        };
        let employees = vec![a, b, c, d, e];
        for em in employees.iter() {
            match try_access(em) {
                Ok(_) => println!("Access Granted"),
                Err(e) => println!("{}", e),
        }
    }
}

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages