更多是從一個前端開發者的角度,來比較一下兩門語言的區別,以助於更方便的入門。
基本類型(DataType)#
多數情況下,基本類型直接代表了最底層的語言實現。
JavaScript 是弱類型,基本數據類型有以下 7 種:
- 字串 (String)
- 數字 (Number)
- 大整數 (BigInt)
- 布林值 (Boolean)
- 符號 (Symbol) ( ECMAScript 2016 新增 )
- null
- undefined
Rust 是 靜態類型 ( statically typed ) 語言,也就是說在編譯時就必須知道所有變量的類型。每一個值都屬於某一個 數據類型 ( data type ),這告訴 Rust 它被指定為何種數據,以便明確數據處理方式。基本都屬於兩類數據類型子集:標量(scalar)和複合(compound)。
整數類型(Integer)
位長度 | 有符號 | 無符號 |
---|---|---|
8-bit | i8 | u8 |
16-bit | i16 | u16 |
32-bit | i32 | u32 |
64-bit | i64 | u64 |
128-bit | i128 | u128 |
arch | isize | usize |
每一個有符號的變體可以儲存包含從 $-(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)。
- 元組是一個將多個其他類型的值組合進一個複合類型的主要方式。
- 元組長度固定:一旦聲明,其長度不會增大或縮小。
- 數組中的每個元素的類型必須相同。
- 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