更多是从一个前端开发者的角度,来比较一下两门语言的区别,以助于更方便的入门。
基本类型(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
相同。
Integer 的表述方法
进制 | 案例 |
---|---|
十进制 | 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 中的数组长度是固定的。
其他
- Vector(
Vec<T>
)- 可变长数组
- Vector 允许我们在一个单独的数据结构中储存多于一个的值,它在内存中彼此相邻地排列所有的值
- String
- 字符串就是作为字节的集合外加一些方法实现的。
- 称作
String
的类型是由标准库提供的,而没有写进核心语言部分,它是可增长的、可变的、有所有权的、UTF-8 编码的字符串类型。
- Map(
HashMap<K, V>
)- 它通过一个 哈希函数(hashing function)来实现映射,决定如何将键和值放入内存中。很多编程语言支持这种数据结构,不过通常有不同的名字:哈希、map、对象、哈希表或者关联数组等等
- 哈希 map 可以用于需要任何类型作为键来寻找数据的情况,而不是像 vector 那样需要通过索引。
变量(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
—EOF—