个人认为,Rust在写一些工程化算法的时候是比较好用的

当我们的模块是偏向于一个较长的算法时,Rust可以确保在编码方面不给你添乱子,同时也保证最终的程序是足够高效的。这里的高效是指,逻辑上应该多快,它就是有多快。
在写C++的时候,我经常因为错写一些语句而搭上双倍的时间复杂度,但Rust很少会有这种情况。

Rust的缺陷在于,目前它依旧不足以说服大多数人去学习这门语言。
因此,如果想要找到更多的使用Rust的机会,如何和其他编程语言共存也成为了一个值得学习的技能点。

❓ 关于pyo3

pyo3是能使Rust和Python之间能够相互进行调用的绑定工具。

本篇文章主要介绍的是如何在Rust当中编写一个函数,然后在Python中去调用它。
这属于FFI编程,有关的介绍,这里有篇不错的文章Rust FFI 编程 - FFI 概述,推荐给大家看看

有关Rust打成Python的包,目前已经有了一些不错的例子。
这里仅以Python的Json序列化组件为例(更多可以查看pyo3 Example),Rust通过pyo3已经有了不错的应用

分别点进去就可以看到,这两个组件在序列化/反序列化速度上都还是比较优秀的。
orjson的测试结果让我也是比较吃惊的,毕竟像Json序列化这种基础组件,Python中也会通过C++来实现。

📋 自查清单

如果你是一名初学者,可以参考以下的自查清单,一方面方便定位一些前置知识,一方面确保能够进行后续的学习。

|
- [ ]

有一个Rust 1.48+的开发环境

- [ ]

| 基本了解Cargo的使用方法 | |
- [ ]

| 有一个Python 3.7+的开发环境 | |
- [ ]

| 基本了解Pip的使用方法 |

📚 指南解读

我也是从用户指南开始学习的,这种情况下,我仅会对指南内容进行一些总结和批注,避免产出不必要的内容。
今天我们要看的内容是:using rust from python

pyo3已经和我去年接触的时候有了很大的变化,已经衍生出了自己的打包工具maturin
maturin是免配置打包,这玩意说白了就是定位给我们这样的小白(或者怕麻烦的人)用的。
当然也有其他的进阶工具,有机会用的话之后我也可以介绍一下。
所以pyo3上来就让你在一个新的文件夹里安装maturin。
如果你是已经写了一些Rust代码的情况,可以在对应的目录只执行后三步命令。
注意:执行_python -m venv .env_这个命令前,要看_python_连接的是否是python 3.7+。

接下来指南会让你在终端跑一个maturin init命令。
这个命令的效果应该类似于新建一个Rust package,只是里面的Cargo.toml maturin会有一个专门的模版。
所以如果是在已有package使用pyo3的情况,我们不需要执行init命令,只需要把Cargo.toml改成指南里要求的格式即可。

下面一步是在Rust当中进行编码。
给你想要接入FFI的函数打上#[pyfunction]宏,再实现一个和Cargo.toml里lib.name一致的module。
比较正常的步骤,安装Rust的惯例,编译器不报错就算成功。

最后就是通过maturin develop打包了。
我自己试的时候,打了文件的IO还有Reqwest请求的逻辑进去,都是成功的,兼容性不错。
这样我们的Rust函数就打包到先前创建的Python虚拟环境里去了。
.env/lib/python3.x/site-packages下你可以看到以lib.name命名的Python包。
如果要在其他环境中也使用这个Python包,把**lib.name****lib.name_py-[version].dist-info**这两个文件夹复制到别的**site-packages**里就可以使用了。

总结

本篇文章简单过了一下pyo3的基本使用方式,经过我个人的体验,每个步骤操作起来是比较简单的,没有出现遇到问题之后不知道去哪里查的情况。

不难看出,这样的打包方式,和操作系统环境是有关联的。我这次是在mac上打的包,那应该只能在mac的Python环境中用这个包,如果需要发布到别的操作系统,或者出现有多个系统需要兼容的情况,针对系统去打包,这种基本的方法需要我们有对应系统的机器,有一些不方便。
之后可以了解一下如何进行交叉编译,如果方便的话会是一种更好的解决办法。

最后,也希望喜欢这篇文章的朋友可以帮忙点个赞 🧡
有不准确或者可以补充的地方也麻烦高手们在评论区提点了 🙏