前言
所有的语言都有一个入门标准,当达到入门标准后想要继续深入达到精通,唯有通过不断的练习
Python
的入门标准比较低,因此颇为流行;JavaScript
的入门难度源于异步的存在所以稍微高一些,而类型化语言更难一些,因为需要考虑额外的上下文因素。
rust
的学习曲线就像是过山车,每当你觉得自己搞明白了,又会下坠到仿佛一无所知的窘境。截止到目前为止,读者还达不到入门的地步,本文将会继续来填补一些空白
语言差异
编程风格
rust
的编程风格和JavaScript
有些许的不同。在rust
中函数、变量、模块的命名方式是下划线式的,如time_in_millis
;结构体则是驼峰式的,如CpuModel
;常量则是大写的下划线方式,如GLOBAL_TIMEOUT
括号的可选性
下面的写法是比较常见的
if (x > y) { /* */ }
while (x > y) { /* */ }
不过下面的方式在rust
中才是首选,上面的写法linter
会给出警告
if x > y { /* */ }
while x > y { /* */ }
表达式返回值
几乎所有完整的代码段都有返回值,如4 * 2
返回8
,if true { 1 } else { 0 }
返回1
,这就意味着你可以将表达式给变量赋值或者作为函数的返回值,如:
fn main() {
let apples = 6;
let message = if apples > 10 {
"Lots of apples"
} else if apples > 4 {
"A few apples"
} else {
"Not many apples at all"
};
println!("{}", message) // prints "A few apples"
}
注意上面的三个字符串后面都没有分号,你可以尝试下加了之后的结果
unit type
rust
没有JavaScript
中的null
和undefined
,不过rust
中依然有“无”这个概念,我们尝试在代码if {} else if {} else {}
中添加分号看看效果:
let message = if apples > 10 {
"Lots of apples"; // ⬅ Notice the rogue semi-colon
} else if apples > 4 {
"A few apples"
} else {
"Not many apples at all"
};
rust
不会进行编译,会给出一个“if and else have incompatible types.”
的提示,完整的输出如下:
error[E0308]: `if` and `else` have incompatible types
--> crates/day-7/syntax/src/main.rs:13:12
|
11 | let message = if apples > 10 {
| ___________________-
12 | | "Lots of apples";
| | -----------------
| | | |
| | | help: consider removing this semicolon
| | expected because of this
13 | | } else if apples > 4 {
| |____________^
14 | || "A few apples"
15 | || } else {
16 | || "Not many apples at all"
17 | || };
| || ^
| ||_____|
| |______`if` and `else` have incompatible types
| expected `()`, found `&str`
输出的信息中会提示你“expected (), found &str.”
,而且还会提示你移除分号,不过提示里的()
是什么意思呢?()
被称为是单位类型(unit type),本质上意味着“无”,一个表达式如果是分号结尾,那么就会返回一个“无”,也叫unit type
。如果我们只在if {}
部分增加了分号,则这部分的返回结果是“无”,编译器希望每个条件分支返回相同的类型,所以当我们删掉分号之后,各个条件分支的返回结果类型就是相同的了。
当你在报错信息中看到()
,就意味着你应该在某处添加或删除分号
函数隐式返回
函数的最后一个执行代码会作为返回值,而不必添加return
声明:
fn add_numbers(left: i64, right: i64) -> i64 {
left + right // ⬅ 注意不加分号
}
和下面的代码是等价的:
fn add_numbers(left: i64, right: i64) -> i64 {
return left + right
}
数组
rust
支持数组,关于数组我们没有讲太多,因为相关文章已经很多了,感兴趣的话可以看 Rust Book: Ch 4.3 和 Rust by Example: Ch 2.3
rust
数组相比于JavaScript
数组的不足之处在于,长度必须固定且初始化的时候每个位置都要有初始值,如下面的代码就有问题:
let mut numbers = [1, 2, 3, 4, 5];
numbers.push(7);
println!("{:?}", numbers);
如果你希望得到得到类似JavaScript
中的那种数组功能,你需要的是 Vec 或 VecDeque,Vec
可以在尾部增减新内容,VecDeque
则是首尾都可以
数组和迭代器在本系列文章中会专门讲,你需要知道的是,有一种简单的宏给一种Vec
相似的能力:
let mut numbers = vec![1, 2, 3, 4, 5]; // ⬅ Notice the vec! macro
numbers.push(7);
println!("{:?}", numbers);
总结
The Rust Book 对于rust
学习者来说非常重要,如果你到目前为止还没读过,那么赶紧去读,不然会遇到很多的麻烦;如果你已经度过,则不妨再读一遍。每当你遇到障碍时,都不妨重新读一读,每次都会有新的发现
在下一篇文章中,我们将会领略rust
中的基础类型,还会展开对结构体的学习