Author: VÕ TRƯỜNG SINH
Theme: Dark Mode
- 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);
}
fn main() {
// Shadowing
let x : u128 = 10;
println!("x: {}", x);
let x: &str = "Hello";
println!("x: {}", x);
}
- 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);
}
- 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);
}
}
|----------------------+----------------------------+-----------------------------------------------------|
| | 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 | |
|----------------------+----------------------------+-----------------------------------------------------|
- Mỗi giá trị trong Rust chỉ có 1 biến được gọi là chủ sở hữu (one variable on owner).
- 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).
- 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();
}
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
}
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);
}
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
}
#[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);
}
#[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");
}
}
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"),
}
}
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);
}
}
#[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();
}
- 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 }
}
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),
}
}
}