源码仓库: github.com/ericlee33/r…
如果文章有帮助的话,欢迎⭐️点赞⭐️,关注我
前言
本文从一个掌握 JavaScript 语言开发者的视角,带你从 JS 的视角理解 Rust 语法,快速上手 Rust 语言
安装 Rust 环境
www.rust-lang.org/learn/get-s…
生成 Rust 项目
我们用类似JSmonorepo的方式组织我们的Rust项目,在./crates目录下
我们用 cargo new tutorials_1命令创建一个项目
启动 Rust 项目
在项目根目录运行cargo run,即可编译并运行项目
如果只想编译,请运行cargo build,会生成二进制可执行文件
教程项目目录结构
通过cargo生成的模板项目,只有main.rs和Cargo.toml。
为了研究Rust模块系统我们额外创建了lib.rs和目录结构图中的文件
入口文件main.rs
在
NodeJs中,为了执行一个程序,需要一个index.js文件,只不过在Rust中是将main.rs定义到了规范中。
当运行Rust项目的时候,会以main.rs的main函数为入口,开始执行程序。
lib.rs用途
在
JS中,我们通过在package.json中指定"main"来决定打包发布后,项目的入口文件。
在Rust中,制定了一套规范,打包后的crate入口为src/lib.rs文件,所以,如果我们的包需要发布,项目中一定需要存在一个lib.rs做入口。
crate: 类似于
JS中package的概念,并且Rust也存在一套类似npm的机制,可见 crates.io/
语法
变量
绑定变量
在Rust中,声明一个变量,只要像js一样声明即可
let x = "hello world";
js支持直接给一个声明后的变量重新赋值,Rust默认是不支持的,如果需要支持,需要如下写法
let mut x = 5;
其中mut关键字代表使该变量可变
变量解构
类似于ES6,Rust也支持变量解构绑定
fn main() {
let (a, mut b): (bool, bool) = (true, false);
println!("a: {}, b: {}", a, b);
b = true;
println!("a: {}, b: {}", a, b);
}
println!是一个宏,类似于js的console.log(),通过 {} 匹配对应位置的变量,第二个参数为 ...args: any[]类型`
单模块导出
大部分Rust教程不会在一开始教模块语法,都是在JS中,我们经常会用到模块导入导出,在ES6中,我们使用import进行导出,
pub、mod
pub类似于es6的export,mod类似于import
mod用途:声明一个模块。用TS的话来说,类似于声明一个namespace的感觉,让我们看看用法
// lib.rs
pub mod same_level_utils;
在lib.rs文件中。
我们通过mod关键字,引用了same_level_utils为一个模块。
添加pub前缀,表面这是一个公开模块,这样我们就将模块导出了。
这里相当于做了类似于
es6的export same_level_utils from 'same_level_utils'的操作
Rust默认有 2 种导入寻找方式:
- 优先寻找文件是否存在,如果有,则导入文件
- 如果该名称文件不存在,寻找是否存在
./same_level_utils的文件夹中的mod.rs文件
这里类似于
js的import utils from './utils',优先寻找./utils.js文件,如果不存在的话,会寻找./utils/index.js文件
我们这里先介绍的是第一种,我们这里的same_level_utils.rs与lib.rs在相同层级
在
TS中,我们在class中也有使用public、private前缀表示属性/方法,是否可供外部访问,和这里是类似的。
// same_level_utils.rs
pub fn print_abc_word() {
println!("abc")
}
让我们看看same_level_utils.rs文件的内容,这里fn关键字表示是一个函数,类似于JS中的function关键词,表示将print_abc_word函数暴露出去。
use
// main.rs
use tutorials_1::same_level_utils;
fn main() {
same_level_utils::print_abc_word();
}
在
JS中,我们使用import关键字导入暴露出的模块
这里我们使用绝对路径的方式引入,注意到我们包的名字为tutorials_1,类似于JS中package.json的name,那么模块命名空间就为tutorials_1
调用或使用嵌套模块的方法也很简单,只要使用两个冒号 (::) 从左到右拼接从外到内的模块即可
print_abc_word其实属于same_level_utils这个命名空间的方法,这里我们通过::的方式引入,执行函数的方式与JS是相同的,使用()执行函数。
让我们看看执行结果:
如何组织目录,更好的模块导出方式
在JS中,我们有时会将工具模块放到utils目录中,那么,在rust中怎么组织呢?
// lib.rs
pub mod utils;
我们在lib.rs中导出utils模块,由于我们的文件夹没有util.rs,他会去寻找utils目录,这种情况下,入口文件为utils/mod.rs,Rust会去识别mod.rs文件,这是一个约定。
// mod.rs
pub mod date;
在mod.rs中,我们导出date模块
// date.rs
use std::time::SystemTime;
pub fn get_current_system_time() -> SystemTime {
SystemTime::now()
}
在date模块中,我们导出get_current_system_time函数,
使用方式
// main.rs
use tutorials_1::same_level_utils;
fn main() {
same_level_utils::print_abc_word();
}
总结
至此,我们熟悉了Rust的变量与模块导入,可以快速创建起来一个项目,并且层级分明。
后言
如果文章对你有帮助,给文章和源码仓库点个赞吧。如果有不懂的地方可以看我资料加微信进行交流。
源码仓库: github.com/ericlee33/r…