环境搭建与工具链:安装Rust、配置Cargo、VS Code插件推荐、第一个并发程序

好,咱们正式开始动手了。这一章说白了就是「把家伙事儿备齐」。我见过太多人卡在环境搭建这一步,其实没必要。跟着我走一遍,十分钟搞定。

安装Rust:rustup 是唯一正解

别去官网手动下载安装包,也别用系统包管理器(比如 apt、brew)。Rust 官方推荐的方式只有一个:rustup。它既是安装器,又是版本管理器,还能随时切换工具链。

核心命令:

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

运行后选默认安装就行。装完记得重启终端,或者手动执行 source $HOME/.cargo/env 让环境变量生效。

验证安装:

rustc --version
cargo --version

看到版本号就对了。我个人习惯装完立刻跑一下 rustup update,确保是最新稳定版。为什么?因为 Rust 的编译错误信息一直在改进,新版能省不少排查时间。

配置Cargo:换源与项目结构

Cargo 是 Rust 的构建系统和包管理器。默认的包下载源在国外,你想想看,每次 cargo build 都要等半天下载依赖,多耽误事。所以第一步就是换源。

~/.cargo/config.toml 里写入:

[source.crates-io]
replace-with = 'ustc'

[source.ustc]
registry = "sparse+https://mirrors.ustc.edu.cn/crates.io-index/"

中科大源目前是最稳的。我曾经试过其他源,偶尔会有同步延迟导致依赖解析失败,换成中科大后再没出过问题。

小技巧:如果你在公司内网,或者网络环境特殊,可以用 cargo install 安装 cargo-local-registry 做本地缓存。对于回测这种高频迭代的场景,本地缓存能省下大量重复下载时间。

VS Code插件推荐

编辑器我推荐 VS Code,不是因为它最好,而是因为生态最全。装好下面这几个插件,开发体验直接起飞:

插件名 作用 为什么重要
rust-analyzer 代码补全、跳转、类型提示 Rust 类型系统复杂,没有它写起来像盲人摸象
CodeLLDB 调试器 并发 bug 最难查,断点调试是刚需
Even Better TOML TOML 文件语法高亮 Cargo.toml 写多了你就知道这个多重要
crates 依赖版本检查 提示哪些依赖有更新,避免用旧版踩坑

装完 rust-analyzer 后,记得打开设置,把 rust-analyzer.cargo.allFeatures 设为 true。不然有些 crate 的特性(feature)没开启,代码提示会不全。嗯,这里要注意,很多新手会忽略这一步。

第一个并发程序:从单线程到多线程

咱们直接写一个回测场景的简化版:计算多只股票的平均收益率。单线程版本长这样:

use std::time::Instant;

fn main() {
    let data = vec![
        vec![0.01, 0.02, -0.01, 0.03, 0.01],
        vec![0.02, -0.01, 0.03, 0.01, 0.02],
        vec![0.01, 0.01, 0.02, -0.01, 0.03],
    ];

    let start = Instant::now();

    let mut results = Vec::new();
    for stock in &data {
        let sum: f64 = stock.iter().sum();
        let avg = sum / stock.len() as f64;
        results.push(avg);
    }

    let duration = start.elapsed();
    println!("单线程耗时: {:?}", duration);
    println!("结果: {:?}", results);
}

这个代码没问题,但数据量一大就慢了。咱们用 std::thread 改成并发版本:

use std::thread;
use std::time::Instant;

fn main() {
    let data = vec![
        vec![0.01, 0.02, -0.01, 0.03, 0.01],
        vec![0.02, -0.01, 0.03, 0.01, 0.02],
        vec![0.01, 0.01, 0.02, -0.01, 0.03],
    ];

    let start = Instant::now();

    let mut handles = vec![];
    for stock in data {
        handles.push(thread::spawn(move || {
            let sum: f64 = stock.iter().sum();
            sum / stock.len() as f64
        }));
    }

    let mut results = vec![];
    for handle in handles {
        results.push(handle.join().unwrap());
    }

    let duration = start.elapsed();
    println!("多线程耗时: {:?}", duration);
    println!("结果: {:?}", results);
}

注意:这里用了 move 关键字把 stock 的所有权移入闭包。如果不加 move,编译器会报错——因为 Rust 无法保证线程的生命周期。我曾经在项目里忘了加 move,排查了半小时才发现,说白了就是所有权机制在并发场景下的体现。

跑一下看看,你会发现多线程版本在数据量小的时候反而可能更慢。为什么?因为线程创建和销毁有开销。但在真实回测场景中,动辄几千只股票、数万条数据,多线程的优势就出来了。

本章知识体系

下面这张图帮你理清本章的核心脉络:

环境搭建与工具链 安装Rust (rustup) 配置Cargo (换源) VS Code插件 第一个并发程序 rustc / cargo 验证 rustup update rust-analyzer CodeLLDB / crates 单线程 → 多线程 move 关键字 / join

说白了,这一章就是打好地基。rustup 装好、Cargo 配好、插件装全、第一个并发程序跑通,后面咱们才能放开手脚搞真正的回测加速。你想想看,如果连环境都没配好,后面讲再高深的并发技巧也是白搭。

避坑指南:我曾经在 Windows 上装 Rust 时忘了装 Visual Studio Build Tools,结果编译 C 依赖时疯狂报错。如果你用 Windows,记得先装 VC++ 生成工具,选上「使用 C++ 的桌面开发」工作负载。macOS 用户确保装了 Xcode Command Line Tools,Linux 用户确保装了 build-essential。

好了,环境搭好了,代码也跑了。接下来咱们就可以深入 Rust 的并发原语了。记住,工具只是手段,理解背后的原理才是关键。


专注资料整理