JoeZhao

跨出界

Hey, I’m JoeZhao, a software engineer, and a gamer.

Rust 基本知識

更多是從一個前端開發者的角度,來比較一下兩門語言的區別,以助於更方便的入門。

基本類型(DataType)#

多數情況下,基本類型直接代表了最底層的語言實現。

JavaScript 是弱類型,基本數據類型有以下 7 種:

  • 字串 (String)
  • 數字 (Number)
  • 大整數 (BigInt)
  • 布林值 (Boolean)
  • 符號 (Symbol) ( ECMAScript 2016 新增 )
  • null
  • undefined

Rust 是 靜態類型 ( statically typed ) 語言,也就是說在編譯時就必須知道所有變量的類型。每一個值都屬於某一個 數據類型 ( data type ),這告訴 Rust 它被指定為何種數據,以便明確數據處理方式。基本都屬於兩類數據類型子集:標量(scalar)和複合(compound)。

整數類型(Integer)

位長度有符號無符號
8-biti8u8
16-biti16u16
32-biti32u32
64-biti64u64
128-biti128u128
archisizeusize

每一個有符號的變體可以儲存包含從 $-(2^{n-1})$ 到 $2^{n-1}-1$ 在內的數字,這裡 $n$ 是變體使用的位數。所以 i8可以儲存從 $-(2^7)$ 到 $2^7-1$ 在內的數字,也就是從 $-128$ 到 $127$ 。無符號的變體可以儲存從 $0$ 到 $2^n-1$ 的數字,所以 u8 可以儲存從 $0$ 到 $2^8-1$ 的數字,也就是從 $0$ 到 $255$。

注意:可以使用以下表格的任何一種形式編寫數字字面值。請注意可以是多種數字類型的數字字面值允許使用類型後綴,例如 57u8 來指定類型,同時也允許使用 _ 做為分隔符以方便讀數,例如1_000,它的值與你指定的 1000 相同。

整數的表述方法

進制案例
十進制98_222
十六進制0xff
八進制0o77
二進制0b1111_0000
字節(只表示 u8 型)b'A'

浮點數類型(Floating-Point Number)

浮點數就是帶小數點的數字。Rust 的浮點數類型是 f32和 f64,分別占 32 位和 64 位。默認類型是 f64,因為在現代 CPU 中,它與 f32 速度幾乎一樣,不過精度更高。所有的浮點型都是有符號的。

布林型(Bool)

標識:bool

  • true
  • false

字符類型(Char)

單引號標識字符類型 (char),雙引號聲明字符串 (str)。

Rust 的 char 類型的大小為四個字節 (four bytes),並代表了一個 Unicode 標量值(Unicode Scalar Value),這意味著它可以比 ASCII 表示更多內容。在 Rust 中,拼音字母(Accented letters),中文、日文、韓文等字符,emoji(繪文字)以及零長度的空白字符都是有效的 char 值。Unicode 標量值包從 U+0000  到 U+D7FF 和 U+E000 到 U+10FFFF 在內的值。不過,「字符」並不是一個 Unicode 中的概念,所以人直覺上的「字符」可能與 Rust 中的 char 並不符合。

複合類型(Compound types)

Rust 有兩個原生的複合類型:元組(tuple)和數組(array)。

  1. 元組是一個將多個其他類型的值組合進一個複合類型的主要方式。
    1. 元組長度固定:一旦聲明,其長度不會增大或縮小。
  2. 數組中的每個元素的類型必須相同。
    1. Rust 中的數組長度是固定的。

其他

  • 向量(Vec<T>
    • 可變長數組
    • 向量允許我們在一個單獨的數據結構中儲存多於一個的值,它在內存中彼此相鄰地排列所有的值
  • 字符串(String)
    • 字符串就是作為字節的集合外加一些方法實現的。
    • 稱作 String 的類型是由標準庫提供的,而沒有寫進核心語言部分,它是可增長的、可變的、有所有權的、UTF-8 編碼的字符串類型。
  • 映射(HashMap<K, V>
    • 它通過一個 哈希函數hashing function)來實現映射,決定如何將鍵和值放入內存中。很多編程語言支持這種數據結構,不過通常有不同的名字:哈希、map、對象、哈希表或者關聯數組等等
    • 哈希 map 可以用於需要任何類型作為鍵來尋找數據的情況,而不是像向量那樣需要通過索引。

變量(Variables)#

var code = 123; // 在舊版本的規範裡,只需要通過 var 關鍵字來聲明
let firstName = "kaby"; // ES6 之後,let 表示變量,允許修改
const lastName = "Zhao"; // ES6 之後,const 表示是常量,不允許修改

firstName = "bike"; // 正常
lastName = "Hu"; // 報錯 - Uncaught TypeError: Assignment to constant variable
// Rust 所有的變量默認都是不允許修改的,如
let code = 123; 
println!("The value of code is: {code}"); // 正常
code = 456; // 拋出錯誤 - cannot assign twice to immutable variable `code`

// 聲明一個允許改變的變量
let mut name = "lulu";
println!("The name is: {name}"); // 輸出 lulu
name = "jack";
println!("The name is: {name}"); // 輸出 jack

// 同樣可以聲明常量的關鍵詞
// 不允許對常量使用 mut
// 常量不光默認不能變,它總是不能變
const WAIT_SEC:u32 = 30;

// 變量隱藏
fn main() {
    let x = 5;
    let x = x + 1;
    {
        let x = x * 2;
				// 12
        println!("The value of x in the inner scope is: {x}");
    }
		// 6
    println!("The value of x is: {x}");
}

函數 & 邏輯#

// 方法的聲明
function getName() {
	return "jack";
}

// 通過變量的方式
let getInfo = function() {
	return {
		"age": 18
	}
}

// 上面也可以使用箭頭表示
let getInfo = () => ({ "age": 18 })

// 邏輯
// 判斷 if / switch
if (getName() == "jack") {
	return "lose";
} else if (getName() == "lose") {
	return "moth";
} else {
	return "";
}

// 循環 for...in / for...of / while
let arr = [1, 2, 3];
for(let i = 0; i < arr.length; i++) {
	console.info(i);
}

// 可以看出來,JavaScript 因為是弱類型語言,會自動對變量類型進行推導和轉化
// 所以對於一些比較和判斷來說比較簡單,直接通過 == 就可以
// 但是也會出現一些意外的情況,比如
// "5" == 5 的結果是 true,這邊要多注意,可以通過 "5" === 5 解決。
// 也可以直接判斷字符串是否相等
// "abc" == "cde"
// 方法
fn main() {
    println!("hello world");

    another_function();

    // print_labeled_measurement
    print_labeled_measurement(5, 'h');

    // plus_one
    let po = plus_one(8);
    // po == 9
    println!("計算結果是 {}", po);

    // do logic_info function
    logic_info("abc", 12);

    // loop
    loop_info();
}

// another_function
fn another_function() {
    println!("another_function");
}

// 帶參數的方法
fn print_labeled_measurement(value: i32, unit_label: char) {
    println!("The measurement is: {value}{unit_label}");
}

// 如果這個方法有返回值的話,還需要定義返回值的類型
fn plus_one(x: i32) -> i32 {
    return x + 1;
}

// 邏輯判斷
fn logic_info(name: &str, age: i32) {
    println!("{} 的年齡是 {} ", name, age);

    // 對於數字類型,可以直接使用 if 比較
    if age > 12 {
        println!("大於 12 歲,需要購買車票");
    } else if age < 12 {
        println!("免費乘車");
    } else {
        println!("12 歲,需要購買車票");
    }

    // 字符串的比較
    if name == "lulu" {
        println!("你好, {}", name);
    } else {
         println!("名字不匹配");
    }
}

// 循環
fn loop_info() {
    // while 循環
    let mut number = 3;
    while number != 0 {
        println!("{number}!");
        number -= 1;
    }
    println!("LIFTOFF!!!");

    // for 循環
    let a = [10, 20, 30, 40, 50];
    for element in a {
        println!("the value is: {element}");
    }

    // loop 循環
    // 注意,loop 循環不會自動終止,需要手動 break
    let mut counter = 0;
    let result = loop {
        counter += 1;
        if counter == 10 {
            break counter * 2;
        }
    };
    println!("loop 循環結果是: {result}");
}

// 可以在這裡查看具體的代碼
// https://play.rust-lang.org/?gist=e87ef95f861dbc22bf8f23722e40aa34
載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。