我是一个 Java 程序员,现在想系统学习一下 Rust。
作为一名经验丰富的 Java 程序员,您已经掌握了编程的核心概念(如变量、循环、函数、面向对象等),这会大大加速您的学习进程。然而,Rust 的核心理念——所有权(Ownership)、借用(Borrowing) 和 生命周期(Lifetimes)——对您来说将是全新的,也是学习的重点和难点。
以下是为您量身定制的系统学习路线图,旨在帮助您平滑地从 Java 过渡到 Rust。
第一阶段:基础入门与思维转变 (1-2 周)
这个阶段的目标是熟悉 Rust 的基本语法和工具链,并开始理解其与 Java 最根本的不同。
- 环境搭建与工具链:
- 安装: 使用
rustup安装 Rust。rustup是 Rust 的版本管理工具,类似于 Java 的jenv或sdkman。 - Cargo: 这是 Rust 的项目管理和构建工具,集成了 Maven/Gradle 的依赖管理和构建功能。学习使用
cargo new,cargo build,cargo run,cargo test。 - IDE/编辑器: 安装 VS Code 并配置
rust-analyzer插件,它能提供类似 IntelliJ IDEA 的智能提示、代码补全和错误检查。
- 安装: 使用
使用 Rust 的项目的源码文件结构是怎样的?什么是 Cargo.toml 文件? 什么是 crates ?
当然,这几个概念是理解 Rust 项目如何组织和构建的基石。对于有 Java 背景的您来说,可以将它们与 Maven/Gradle 的概念进行类比,会更容易理解。
1. Rust 项目的源码文件结构
Rust 的项目结构遵循一套简单且强大的约定。当您使用 Cargo 创建一个新项目时,它会自动生成这个标准结构。
1.1. 二进制应用 (Binary Application)
如果您要创建一个可执行程序(类似于一个包含 main 方法的 Java 项目),可以运行:
Bash
cargo new my_app
Cargo 会生成如下结构:
my_app
├── .git/
├── .gitignore
├── Cargo.toml
└── src/
└── main.rs
my_app/: 项目的根目录。Cargo.toml: 项目清单文件,我们稍后会详细讲解。src/: 存放所有源代码的目录,完全等同于 Java 项目中的src/main/java。src/main.rs: 二进制项目的根文件和入口。fn main() { ... }函数必须定义在这里,它就是程序的起点,等同于 Java 的public static void main(String[] args) {}。
1.2. 库 (Library)
如果您要创建一个可复用的库(类似于一个要打包成 JAR 的 Java 库项目),可以运行:
Bash
cargo new my_lib --lib
结构会略有不同:
my_lib
├── .git/
├── .gitignore
├── Cargo.toml
└── src/
└── lib.rs
src/lib.rs: 库项目的根文件。这个文件定义了库对外暴露的公共 API。它没有main函数。
1.3. 模块化(组织代码)
当代码变得复杂时,您需要将其拆分到不同文件中。这类似于 Java 的包(package)。
例如,您可以这样组织代码:
src/
├── main.rs
├── network.rs
└── network/
└── client.rs
要在 main.rs 中使用这些模块,您需要声明它们:
Rust
// 在 main.rs 中
mod network; // 声明 src/network.rs 是一个模块
fn main() {
println!("Hello from main!");
// 使用 network 模块中的函数或 client 子模块
network::connect();
network::client::ping();
}
而在 network.rs 中,您需要声明它的子模块:
Rust
// 在 src/network.rs 中
pub mod client; // 声明 network/client.rs 是一个子模块
pub fn connect() {
println!("Connecting...");
}
mod network;告诉编译器去查找src/network.rs或者src/network/mod.rs文件,并将其内容编译为一个名为network的模块。- 这套模块系统是 Rust 组织代码、控制可见性(
pub关键字)的核心。
2. Cargo.toml 文件是什么?
Cargo.toml 是 Rust 项目的清单文件,采用 TOML 格式。
它完全可以类比为 Java 世界的 pom.xml (Maven) 或 build.gradle (Gradle)。 它负责定义项目的所有元数据和依赖项。
一个典型的 Cargo.toml 文件包含以下几个部分:
Ini, TOML
# [package] 部分定义了项目的核心元数据
[package]
name = "my_app" # 项目名称 (crate 名称)
version = "0.1.0" # 项目版本号,遵循语义化版本
edition = "2021" # 使用的 Rust 版本(例如 2015, 2018, 2021),会影响一些语法特性
# [dependencies] 部分定义了项目运行时需要的依赖库
# 这等同于 pom.xml 中的 <dependencies> 标签
[dependencies]
serde = { version = "1.0", features = ["derive"] } # 引入 serde 库
rand = "0.8.5" # 引入 rand 库
tokio = { version = "1", features = ["full"] } # 引入 tokio 异步运行时
# [dev-dependencies] 部分定义了仅在测试、示例或基准测试时才需要的依赖
# 这等同于 pom.xml 中 <scope>test</scope> 的依赖
[dev-dependencies]
criterion = "0.4"
核心功能:
- 项目描述: 定义项目的名称、版本、作者等。
- 依赖管理: 当您在
[dependencies]中添加一个库时,运行cargo build或cargo run,Cargo 会自动从官方仓库 crates.io 下载并编译该依赖及其所有子依赖。 - 构建配置: 您还可以定义不同的构建配置(Profiles),例如为开发构建(
dev)和发布构建(release)设置不同的优化级别。
3. Crates 是什么?
Crate 是 Rust 中最小的编译单元。
您可以将一个 Crate 类比为一个 Java 的 JAR 文件。它要么是一个可执行程序(Runnable JAR),要么是一个库(Library JAR)。
Crate 有两种类型:
- 二进制 Crate (Binary Crate):
- 是一个可编译成可执行文件的程序。
- 必须包含一个
fn main()函数作为程序入口。 - 项目的
src/main.rs文件默认就是这个二进制 Crate 的根文件。 - 一个项目可以包含多个二进制 Crate(例如在
src/bin/目录下创建多个.rs文件)。
- 库 Crate (Library Crate):
- 是一系列功能的集合,旨在被其他项目作为依赖使用。
- 没有
fn main()函数。 src/lib.rs文件是一个库 Crate 的根文件。- 一个项目(包)最多只能有一个库 Crate。
总结与类比
为了让您更好地理解这三者之间的关系,这里有一个总结:
| Rust 概念 | Java 类比 | 描述 |
|---|---|---|
| Package | Maven/Gradle 项目 | 一个由 Cargo.toml 文件定义的项目。一个 Package 可以包含一个库 Crate 和多个二进制 Crate。 |
| Crate | JAR 文件 | 一个编译单元。可以是库 (Library) 或可执行程序 (Binary)。 |
Cargo.toml |
pom.xml / build.gradle |
项目的清单和构建配置文件,用于管理元数据和依赖。 |
crates.io |
Maven Central | Rust 的官方公共包(Crate)仓库。 |
src/main.rs |
src/main/java/com/mycompany/Main.java |
二进制 Crate 的入口文件,包含 main 函数。 |
src/lib.rs |
src/main/java/ (整个包) |
库 Crate 的根文件,定义了库的公共 API。 |
Module (mod) |
Package (package com.mycompany;) |
在一个 Crate 内部组织代码、控制可见性的方式。 |
介绍一下 rust 项目的模块化机制
好的 👍。Rust 的模块化机制和 Java 的 package/module 概念有点像,但更底层、更接近文件系统。整体来说,Rust 的 模块系统 (module system) 由 四个部分组成:
- 包 (Package)
- 板条箱 (Crate)
- 模块 (Module)
- 路径 (Path)
我帮你逐层对比一下 Java,让你更好理解。
1. 包 (Package)
- 一个 package 是由一个或多个 crate 组成的集合。
- 必须包含一个
Cargo.toml文件,描述依赖和元数据。 - 👉 类比:Java 里的 Maven/Gradle 项目。
例子:
|
|
2. 板条箱 (Crate)
- crate 是编译的最小单元,可以生成 库 (library) 或 二进制 (binary)。
- 默认情况下:
src/main.rs定义一个 binary crate(类似 Java 的public static void main入口)。src/lib.rs定义一个 library crate(类似 Java 的库 Jar)。
- 👉 类比:Java 的 Jar 包。
例子:
|
|
3. 模块 (Module)
- module 用来组织代码,相当于 Java
package,但与文件系统紧密对应。 - 用
mod关键字声明:- 可以放在同一个文件里(内联模块)。
- 也可以拆到单独文件/目录。
例子:
单文件模块
|
|
目录模块
|
|
👉 Rust 的 mod.rs 类似 Java 的 package-info.java,作为目录模块的入口。
from Mark: *.rs 文件名即 mod 名。
4. 路径 (Path) 与可见性
- Rust 默认 私有 (private),需要显式
pub才能被外部访问。 - 访问路径用
::,类似 Java 的点号.。 - 特殊关键字:
self:当前模块(类似 Java 的this package)。super:父模块(类似 Java 的..上级包)。crate:当前 crate 根(类似 Java 项目根)。
例子:
|
|
Java vs Rust 模块化对比
| 概念 | Java | Rust |
|---|---|---|
| 项目 | Maven/Gradle Project | Package (Cargo.toml) |
| 编译单元 | Jar | Crate (binary/lib) |
| 命名空间 | Package (com.example.util) |
Module (mod util;) |
| 入口 | public static void main(String[]) |
fn main() |
| 可见性 | public / protected / private |
pub (默认 private) |
| 组织结构 | 文件夹 + .java 文件 |
文件夹 + .rs 文件 (mod.rs 可选) |
⚡ 关键点总结:
- Rust 的 模块系统是基于文件系统的,而 Java 是基于包名(字符串)。
- Rust 默认私有,要导出必须加
pub。 crate是项目内的根,mod用来声明模块。- 文件/目录结构 就是模块结构(跟 Java 有点像,但更严格)。
要不要我帮你画一张 Rust 模块系统结构图,用目录树和对应的 mod 声明,把 crate → module → path 的关系直观表现出来?