第 10 章:Maven 的 XML 地狱受够了吗?Gradle 的 Groovy 脚本恶心不?

恭喜你,解脱的时候到了。

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 的世界里,测试不是事后的补充,而是开发过程的核心部分。