恭喜你,解脱的时候到了。
Cargo 不只是一个构建工具,它是项目管理的终极解决方案。一个工具搞定依赖管理、构建、测试、文档、发布——Maven 和 Gradle 联手都做不到的事情。
是时候见识真正的现代化工具链了。
Java 构建工具:功能强大,体验糟糕
Maven:XML 的噩梦
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>my-app</artifactId>
<version>1.0.0</version>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
</dependencies>
</project>
加个依赖要写这么多垃圾?
Gradle:复杂度爆炸
plugins {
id 'java'
id 'application'
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.apache.commons:commons-lang3:3.12.0'
testImplementation 'junit:junit:4.13.2'
}
application {
mainClass = 'com.example.Main'
}
tasks.withType(JavaCompile) {
options.encoding = 'UTF-8'
}
看起来简洁?等你项目复杂了再说。
Cargo:优雅到令人发指
项目创建:一条命令搞定
cargo new my-project
cd my-project
就这样,项目创建完成。
目录结构自动生成:
my-project/
├── Cargo.toml # 项目配置,相当于 pom.xml
├── src/
└── main.rs # 主程序入口
Cargo.toml:简洁得不像话
[package]
name = "my-project"
version = "0.1.0"
edition = "2021"
[dependencies]
serde = "1.0"
tokio = { version = "1.0", features = ["full"] }
就这样,依赖声明完成。 没有 XML 的噪音,没有插件的复杂性,没有 repository 的配置。
需要测试依赖?
[dev-dependencies]
assert_cmd = "2.0"
需要条件编译?
[target.'cfg(unix)'.dependencies]
libc = "0.2"
简洁到令人不敢置信。
Rust 的代码组织:比 Java 更清晰
Crate:编译的基本单位
Java 的 JAR: 运行时的产物,包含编译后的字节码 Rust 的 Crate: 编译时的单位,更精确的控制
// Binary Crate (可执行程序)
fn main() {
println!("Hello, world!");
}
// Library Crate (库代码)
pub fn add(a: i32, b: i32) -> i32 {
a + b
}
一个 Package 可以包含:
- 最多 1 个 library crate
- 任意数量的 binary crates
比 Java 的模块系统清晰多了。
Module:命名空间的完美实现
// Java 的包声明
package com.example.utils;
public class StringUtils { }
// Rust 的模块声明
mod utils {
pub mod string {
pub fn capitalize(s: &str) -> String {
// 实现
}
}
}
// 使用
use utils::string::capitalize;
Rust 的模块系统比 Java 的包系统更灵活、更清晰。
Cargo 命令:一个工具统治一切
构建和运行
cargo build # 构建项目
cargo run # 构建并运行
cargo build --release # 优化构建
cargo check # 快速检查,不生成二进制文件
对比 Maven:
mvn compile # 只编译
mvn exec:java # 运行
mvn package # 打包
mvn test # 测试
Cargo 的命令更直观、更快速。
依赖管理:自动化到极致
cargo add serde # 添加依赖
cargo remove serde # 删除依赖
cargo update # 更新所有依赖
cargo tree # 显示依赖树
Maven 做这些需要多少步骤?Cargo 一条命令搞定。
测试:内置支持
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_add() {
assert_eq!(add(2, 3), 5);
}
}
cargo test # 运行所有测试
cargo test test_add # 运行特定测试
cargo test --release # 优化模式测试
测试和代码在一起,无需额外配置。
文档:一等公民
/// 计算两个数的和
///
/// # Examples
///
/// ```
/// assert_eq!(add(2, 3), 5);
/// ```
pub fn add(a: i32, b: i32) -> i32 {
a + b
}
cargo doc --open # 生成并打开文档
文档即代码,测试即文档。 Java 的 JavaDoc 相比之下就是原始工具。
性能对比:Cargo 完胜
构建速度
Maven/Gradle:
- 冷启动慢(插件加载)
- 增量编译支持有限
- JVM 启动开销
Cargo:
- 原生编译器,启动快
- 增量编译默认开启
- 并行编译优化
依赖解析
Maven:
mvn dependency:resolve # 几秒到几分钟
Cargo:
cargo build # 依赖解析自动完成,几毫秒
缓存机制
Cargo 的缓存策略比 Maven 更智能:
- 全局依赖缓存
- 增量编译缓存
- 跨项目共享
Workspace:多项目管理的艺术
Java 的多模块项目
<!-- 父 pom.xml -->
<modules>
<module>module-a</module>
<module>module-b</module>
<module>module-c</module>
</modules>
配置复杂,依赖管理困难。
Rust 的 Workspace
# Cargo.toml (workspace root)
[workspace]
members = [
"crate-a",
"crate-b",
"crate-c"
]
[workspace.dependencies]
serde = "1.0" # 统一版本管理
一个配置文件,统一管理所有子项目。
发布:从开发到生产的一键部署
Maven 的发布流程
mvn clean compile test package install deploy
# 还要配置 settings.xml
# 还要处理 GPG 签名
# 还要上传到各种仓库
Cargo 的发布流程
cargo login <token>
cargo publish
就这样,包发布到 crates.io。 全球 Rust 开发者都能使用你的包。
写在最后:工具链的代际差异
Maven 和 Gradle 是上一代的构建工具:
- 功能强大但配置复杂
- 插件生态丰富但版本冲突频繁
- XML/Groovy 配置冗长且不直观
Cargo 是下一代的构建工具:
- 功能全面且配置简洁
- 工具链统一且版本一致
- TOML 配置清晰且直观
这就是工具链进化的力量。
当你习惯了 Cargo 的简洁和高效,再回到 Java 的构建工具时,你会感觉像是从现代化的智能汽车换回了手摇启动的老爷车。
下一章我们要学习 Rust 的测试系统。 准备好体验真正的现代化测试框架了吗?
因为在 Rust 的世界里,测试不是事后的补充,而是开发过程的核心部分。