我是一个 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 的关系直观表现出来?