[Rust] Rust 學習筆記 - 基本概念篇

繼上篇猜數字的練習範例中,大致上可以感受到 Rust 這語言的個性,但還是得知道語言的型別、語法及流程控制的方法,所以這邊筆記會針對 Command Programming Concepts 章節 的內容擷取我覺得需要記下來的重點

Variables and Mutability

  • 變數宣告後,預設皆為不可改變的狀態 (Immutable),如果需要一個可以被改變的變數,必須加上 mut 的關鍵字

    1
    2
    3
    4
    let a = 1; // immutable
    a = 2; // 這行會出錯
    let mut b = "some text";
    b = "can be changed";
  • 變數的型別必須要一致,直到重新被宣告 (Shadowing)

    1
    2
    3
    4
    let a = "1";
    let a = a.len();
    let mut b = "some text";
    b = b.len(); // 型別不一致,會發生錯誤
  • variables 與 constants 的差異有以下幾點

    • constants 不能使用 mut
    • constants 使用 const 宣告而且必須指定型別,範例: const MAX_POINTS: u32 = 100_000;
    • constants 只能被宣告一次

Data Types

Scalar Type

Rust 的標準型別 (scalar type) 有四種: integersfloating-point numbersBooleanscharacters

Integer

  • 分為 signed (i) 和 unsigned (u)

  • 有 8-bit、16-bit、32-bit、64-bit、128-bit、arch 長度

  • 8 ~ 128 bit 的範圍算法說明如下

    Each signed variant can store numbers from -(2n - 1) to 2n - 1 - 1 inclusive, where n is the number of bits that variant uses. So an i8 can store numbers from -(27) to 27 - 1, which equals -128 to 127. Unsigned variants can store numbers from 0 to 2n - 1, so a u8 can store numbers from 0 to 28 - 1, which equals 0 to 255.

    Additionally, the isize and usize types depend on the kind of computer your program is running on: 64 bits if you’re on a 64-bit architecture and 32 bits if you’re on a 32-bit architecture.

  • 可以使 _ 來增加數字的閱讀性,例如: 100_000 等同於 100000

floating-point

  • f32f64 兩種 floating-point type
  • 根據 IEEE-754 標準 (wiki)

Boolean

  • 如一般使用 truefalse 兩種結果,大小為 1 byte

    1
    2
    3
    4
    5
    fn main() {
    let t = true;

    let f: bool = false; // with explicit type annotation
    }

Character

  • 基本文字型使用雙引號包起來,而 character 使用單引號,跟 C# 一樣

    1
    2
    3
    4
    5
    fn main() {
    let c = 'z';
    let z = 'ℤ';
    let heart_eyed_cat = '😻';
    }

Compound Types

Tuple

  • 宣告方式

    1
    2
    3
    4
    fn main() {
    let tup1 = (500, 6.4, 1);
    let tup2: (i32, f64, u8) = (500, 6.4, 1);
    }
  • 解構 tuple

    1
    2
    3
    4
    5
    6
    7
    fn main() {
    let tup = (500, 6.4, 1);

    let (x, y, z) = tup;

    println!("The value of y is: {}", y);
    }
  • 直接使用 index 讀取 tuple

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    fn main() {
    let x: (i32, f64, u8) = (500, 6.4, 1);

    let five_hundred = x.0;

    let six_point_four = x.1;

    let one = x.2;
    }

Array

  • 宣告方式

    1
    2
    let a = [1, 2, 3, 4];
    let b = [1; 5]; // [1,1,1,1,1]
  • with 型別及長度宣告

    1
    let a: [i32; 5] = [1, 2, 3, 4, 5];
  • 從 0 開始,超過陣列長度會造成錯誤

Functions

  • 宣告方式: fn

  • 命名方式: snake case,範例: fn another_function(){ }

  • Function parameters 的設定方式

    1
    2
    3
    4
    5
    6
    7
    fn main() {
    another_function(5);
    }

    fn another_function(x: i32) {
    println!("The value of x is: {}", x);
    }
  • Expression in Function

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    fn main() {
    let x = 5;

    let y = {
    let x = 3;
    x + 1
    };

    println!("The value of y is: {}", y);
    }
    • 使用 { } 來建立一個新的 scope
    • line 6: 沒有分號結尾,視為 expression 會被 return
  • Function 需回傳 values 或是 expressions,沒有 void 的概念

Comments

  • 註解符號為 : //

    1
    2
    3
    4
    fn main() {
    // I’m feeling lucky today
    let lucky_number = 7;
    }

Control Flow

流程控制有 ifloops 兩種方法

if

  • 語法,if 後面的條件不需要使用 ( ) 包起來

    1
    2
    3
    4
    5
    6
    7
    8
    9
    fn main() {
    let number = 3;

    if number < 5 {
    println!("condition was true");
    } else {
    println!("condition was false");
    }
    }
  • else if 這種東西

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    fn main() {
    let number = 6;

    if number % 4 == 0 {
    println!("number is divisible by 4");
    } else if number % 3 == 0 {
    println!("number is divisible by 3");
    } else if number % 2 == 0 {
    println!("number is divisible by 2");
    } else {
    println!("number is not divisible by 4, 3, or 2");
    }
    }
  • 可以搭配 let 使用,但回傳的型別必須一致

    1
    2
    3
    4
    5
    6
    fn main() {
    let condition = true;
    let number = if condition { 5 } else { 6 };

    println!("The value of number is: {}", number);
    }

loops

有三種 loops 的方式: loopwhilefor

  • loop

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    fn main() {
    let mut counter = 0;

    let result = loop {
    counter += 1;

    if counter == 10 {
    break counter * 2;
    }
    };

    println!("The result is {}", result);
    }
  • while

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    fn main() {
    let mut number = 3;

    while number != 0 {
    println!("{}!", number);

    number -= 1;
    }

    println!("LIFTOFF!!!");
    }
  • for

    1
    2
    3
    4
    5
    6
    7
    fn main() {
    let a = [10, 20, 30, 40, 50];

    for element in a.iter() {
    println!("the value is: {}", element);
    }
    }

小結

Rust 沒有像 C# 擁有很多不同型別或是程式語法,但這些都算是基本需要掌握的,如果有地方理解錯誤也請讓我知道,感謝