如果你曾经想要将Rust的语言能力与Jupyter笔记本的交互性结合起来,那么你来对地方了。也许你厌倦了每次测试代码片段时都需要进行编译;或者你想以一种更互动的方式学习Rust;又或者,就像我一样,突然有了一个奇思妙想。

大多数人认为Jupyter只是用于Python和数据科学相关的工作,但事实上,在Jupyter中也可以运行Rust代码。

在这个教程中,我们将了解以下内容:

  1. 什么是EvCxR?

  2. 如何安装Rust Jupyter内核

  3. 如何在笔记本中运行你的第一段Rust代码

  4. 实用的小技巧

  5. 常见问题及解决方法

  6. 何时不应使用Jupyter来编写Rust代码

重要声明:本教程假定你已经掌握了Rust和Jupyter的基础知识。如果你在操作过程中出了问题,那可就只能自担责任了哦 🙂。

那么,不再耽搁了,让我们开始吧。

什么是EvCxR?

EvCxR(对我的语言学同行来说,这个名称听起来简直像“评估器”……)实际上是一个Rust交互式编译环境以及Jupyter内核。它能让你在Jupyter笔记本中直接运行Rust代码,而无需经历传统的编译-运行-调试流程。

这个名字的含义是“Rust的评估环境”,而且这是一个在GitHub上持续维护的开源项目。以下是这个工具之所以如此出色的几个原因:

  1. 交互式开发:你可以随时测试Rust代码片段,而无需创建整个项目。

  2. 原型设计:在正式投入开发之前,你可以快速尝试各种想法。

  3. 数据可视化:你甚至可以用Rust来绘制图表哦(具体方法稍后介绍)。

如何安装Rust Jupyter内核

先决条件

在开始安装之前,请确保你已经具备了以下条件:

  1. Linux系统:或者至少需要安装Windows Subsystem for Linux(针对Windows用户还有特别说明)。

  2. Rust工具链:如果你还没有安装,可以从rustup.rs下载。

  3. Jupyter:通过pip进行安装——命令是pip install jupyter

  4. 耐心:整个安装过程可能需要一两分钟的时间。

一旦准备就绪,我们就可以开始使用Rust了。

注意:如果你使用的是Windows系统,还需要进行一些额外的配置。具体步骤如下:……

  1. 访问 https://visualstudio.microsoft.com/visual-cpp-build-tools/

    步骤1:安装EvCxR

    打开终端并运行以下命令:

    cargo install evcxr_jupyter
    

    现在去喝杯咖啡吧 ☕。这个过程需要几分钟时间,因为Cargo会下载并编译所有所需的文件。如果看起来进度停滞了,也别慌——Rust的编译过程虽然比较细致,但速度确实不快。

    如果你遇到因系统库缺失而导致的错误,可能需要安装一些依赖项。在Ubuntu/Debian系统中,可以尝试以下命令:

    sudo apt install jupyter-notebook jupyter-core python-ipykernel
    sudo apt install cmake
    

    在macOS系统上使用Homebrew时,则运行:

    brew install cmake jupyter
    

    步骤2:安装Jupyter内核

    安装完成后,你需要将EvCxR内核注册到Jupyter系统中:

    evcxr_jupyter --install
    

    最后你应该会看到类似这样的输出信息:

    安装完成

    步骤3:启动Jupyter并创建一个Rust笔记本

    让我们来测试一下这个新工具吧。首先启动Jupyter:

    jupyter notebook
    

    你的浏览器应该会自动打开窗口(如果没有打开,可以从终端中复制URL地址并粘贴进去)。

    在Jupyter界面中:

    1. 点击右上角的新建按钮

    2. 从下拉菜单中选择Rust选项

    3. 一个新的笔记本就会打开

    欢迎使用交互式的Rust编程环境!🦀

    步骤4:编写你的第一段Rust代码

    让我们从最基础的示例开始:

    println!("Hello my fellow Rustaceans! 🦀");
    

    Shift + Enter键运行这段代码,你应该会看到结果显示在页面下方。就是这么简单。

    需要注意的是,Rust笔记本中的代码是直接在顶层执行的,因此不需要使用main()函数来包裹代码。不过如果你还是想这样做,可以按照以下方式编写:

    fn main(){
        println!("Hello my fellow Rustaceans! 🦀");
    }
    // 调用函数
    main()
    

    现在我们来尝试一些更有趣的例子:

    fn fibonacci(n: u32) -> u32 {
        match n {
            0 => 0,
            1 => 1,
            _ => fibonacci(n - 1) + fibonacci(n - 2)
        }
    }
    
    for i in 0..10 {
        println!("fibonacci({}) = {}", i, fibonacci(i));
    }
    

    运行这段代码,你会看到斐波那契数列的生成过程。

    fibonacci(0) = 0
    fibonacci(1) = 1
    fibonacci(2) = 1
    fibonacci(3) = 2
    fibonacci(4) = 3
    fibonacci(5) = 5
    fibonacci(6) = 8
    fibonacci(7) = 13
    fibonacci(8) = 21
    fibonacci(9) = 34
    

    实用小贴士

    在笔记本中使用Rust时,不仅仅是函数的行为会发生变化,还有其他一些需要注意的地方:

    变量在不同代码块中依然有效

    与传统的Rust编译方式不同,在一个代码块中定义的变量会在后续的代码块中继续使用:

    let mut counter = 0;
    

    然后在下一个代码块中:

    counter += 1;
    println!("Counter: {}", counter);
    

    输出结果将会是:

    Counter: 1

    这种方式非常适合逐步构建复杂的示例程序。

    你可以使用外部库

    可以在一个代码块中使用`:dep`命令添加依赖项:

    :dep serde = { version = "1.0", features = ["derive"] }
    :dep serde_json = "1.0"
    

    然后在后续的代码中正常使用这些依赖库:

    use serde::{Serialize, Deserialize};
    
    #[derive(Serialize, Deserialize, Debug)]
    struct Person {
        name: String,
        age: u32,
    }
    
    let person = Person {
        name: "Amina".to_string(),
        age: 24,
    };
    
    let json = serde_json::to_string(&person).unwrap();
    println!("{}", json);
    

    输出结果:

    {"name":"Amina","age":24}

    相当方便,对吧?

    支持数据可视化

    你甚至可以创建图表。首先需要安装`plotters`库:

    :dep plotters = { version = "0.3", default-features = false, features = ["evcxr", "all_series", "bitmap_backend", "bitmap_encoder"] }
    

    然后就可以创建一个简单的正弦波图表了:

    use plotters::prelude::*;
    
    let root = SVGBackend::new("sine_wave.svg", (640, 480)).into_drawing_area();
    root.fill(&WHITE).unwrap();
    
    let mut chart = ChartBuilder::on(&root)
        .caption("Sine Wave", ("Arial", 20))
        .margin(5)
        .x_label_area_size(30)
        .y_label_area_size(30)
        .build_cartesian_2d(-3.14..3.14, -1.2..1.2)
        .unwrap();
    
    chart.configure_mesh().draw().unwrap();
    
    chart.draw_series(LineSeries::new(
        (-314..314).map(|x| {
            let x = x as f64 / 100.0;
            (x, x.sin())
        }),
        &RED,
    )).unwrap();
    
    root.present().unwrap();
    println!("图表已保存为sine_wave.svg");
    

    输出结果:

    正弦波图表

    关于图表显示的说明:你其实可以直接在笔记本中内嵌显示图表。但如果你使用的是WSL与VSCode组合环境(就像我一样),由于笔记本界面的渲染问题,内嵌图表可能无法正常显示。因此,我将图表保存为svg文件,这样就可以在文本编辑器中方便地查看它了。

    检查类型

    不确定某个变量的数据类型是什么?可以使用`:vars`命令来查看所有变量及其类型:

    let x = vec![1, 2, 3];
    
    :vars
    

    输出结果:

    变量          类型
           x Vec

    常见问题及解决方法

    到处都会出现编译错误

    如果遇到了奇怪的编译错误,请记住以下几点:

    • 每个代码单元都是单独进行编译的

    • 你可能需要在每个代码单元中重新导入所需的依赖项

    执行速度缓慢

    第一次运行代码时,由于编译的开销,执行速度会比较慢。后续再次运行时速度会快一些。如果速度仍然很慢,你可以尝试以下方法:

    • 使用发布模式::opt 2

    • 只保留真正需要的依赖项

    • 思考一下Jupyter是否适合你的需求

    依赖项无法加载

    如果某个依赖包无法被成功加载,请尝试以下方法:

    • 确认该版本确实存在于crates.io

    • 检查你的网络连接是否正常(因为需要下载依赖包)

    • 尝试明确指定所需的依赖功能

    • 如果问题依然存在,可以清除cargo缓存:rm -rf ~/.evcxr

    何时不适合使用Jupyter进行Rust开发

    Jupyter笔记本非常适合学习和实验,但在以下情况下它们并不一定是最佳选择:

    • 生产环境代码:应使用标准的cargo项目结构进行开发

    • 对性能要求极高的代码:Jupyter带来的开销并不值得

    • 大型应用程序:使用笔记本会导致代码结构变得非常混乱

    • 团队协作:使用笔记本进行版本控制会带来很多麻烦

    • 对于原型设计和快速实验来说,Jupyter笔记本是非常合适的工具。但对于任何较为复杂的项目,建议使用你喜欢的编辑器来创建正规的Rust项目。

      总结

      让我们总结一下今天学到的内容:

      1. 如何安装EvCxR Jupyter内核

      2. 如何创建和运行Rust笔记本

      3. 如何在笔记本中使用外部依赖包

      4. 交互式Rust开发的一些实用技巧

      Jupyter笔记本让学习和使用Rust变得更加方便。下次当你想快速尝试一些Rust代码时,不妨试试这个工具,而无需花费时间创建完整的项目结构。至此,本教程就结束了。

      祝大家学习顺利!

      资源链接

      1. EvCxR GitHub仓库

      2. Rust官方文档

      3. Jupyter文档

      致谢

      感谢Anuoluwapo VictorChinaza NwukwaHolumidey MercyFavour OjoGeorginaAwani,以及我的家人,感谢你们提供的灵感、支持和知识,帮助我完成了这篇教程的编写。

      <感谢 EvCxR 项目的维护者们让这一切成为可能,也感谢 Rust 社区的各位成员,以及所有愿意学习这些知识的人。你们每一天都在激励着我。>

Comments are closed.