rust_in_flutter:用rust辅助开发flutter应用,支持跨平台桌面、安卓、iOS开发,性能优势
轻松集成 Rust 以使您的 Flutter 应用程序变得极快!

该软件包在设计时考虑了易用性、未来的可扩展性和卓越的性能,可处理幕后的所有复杂方面。只需将此包添加到您的 Flutter 项目中,您就可以编写 Rust 了!
好处
- Rust 集成,能够使用任意数量的库箱
- 不会弄乱敏感的构建文件,如CMake,Gradle,Podfile等
- 在开发过程中无需生成复杂的代码
- 定义无限的 RESTful API 端点,无需太多努力
- 异步交互,来自 Dart 的简单请求和来自 Rust 的响应
- 从 Rust 流向 Dart
- 在 Dart 的热重启上重新启动 Rust 逻辑
- 最小开销
- 发送本机数据时没有内存副本
平台支持
所有具有挑战性的构建设置都由此包自动处理。请注意,Flutter 项目中的文件不受影响。
- ✅ Linux:经过测试和支持
- ✅ 安卓:经过测试和支持
- ✅ 视窗:经过测试和支持
- ✅ macOS:经过测试和支持
- ✅ iOS:经过测试和支持
- ⏸️ Web:不是现在,而是考虑
为什么要使用 Rust?
虽然Dart是一种了不起的面向对象的现代语言,但它的性能有时不符合要求,因为它是非原生垃圾收集语言。这就是 Rust 发挥作用的地方。众所周知,Rust 的性能大约比 Dart 快 2~40 倍,更不用说利用多个线程的能力了。
👜 安装组件
基本步骤
首先,将此包添加到您的 Flutter 项目中。
flutter pub add rust_in_flutter
然后安装 Rust 工具链。请参考官方 Rust 文档。
最后,检查您的系统是否已准备好进行编译。您可以在每个安装步骤后重复这些命令以验证系统状态。如果输出中没有问题,您就可以开始了!
rustc --version
flutter doctor
额外步骤
如果您打算为 Linux、Windows、macOS 或 iOS 编译代码,则无需执行任何其他步骤。
对于安卓,安装安卓 NDK 版本要求23.1.7779620
。
在 Rust 中使用额外的构建目标有时会带来各种问题。如果您遇到任何问题,请随时访问讨论页面并打开问答线程寻求帮助。
👜 应用模板
只需在 Flutter 项目文件夹的命令行中运行它即可。
dart run rust_in_flutter:apply_template
运行命令后,将有一些新的文件夹和文件将成为您的入门 Rust 模板。
my_flutter_project/
├── android/
├── ios/
├── lib/
├── linux/
+ ├── native/
+ │ ├── hub/
+ │ │ ├── src/
+ │ │ └── Cargo.toml
+ │ ├── sample_crate/
+ │ │ ├── src/
+ │ │ └── Cargo.toml
+ │ └── README.md
├── web/
├── windows/
* ├── .gitignore
+ ├── Cargo.toml
* ├── pubspec.yaml
└── ...
不要忘记先阅读文件。此外,您可能希望在生产中删除。./native/README.md
sample_crate
现在转到 ,您可以开始编写 Rust!./native/hub/src/lib.rs
🧱 技巧
从 Dart 请求时,应指定操作和地址。这种通信方式遵循 RESTful API 的定义。
import 'package:rust_in_flutter/rust_in_flutter.dart';
import 'package:msgpack_dart/msgpack_dart.dart';
void someFunction() async {
var rustRequest = RustRequest(
address: 'basicCategory.counterNumber',
operation: Operation.Read,
bytes: serialize(
{
'letter': 'Hello from Dart!',
'before_number': 888,
'dummy_one': 1,
'dummy_two': 2,
'dummy_three': [3, 4, 5]
},
),
);
var rustResponse = await requestToRust(rustRequest);
var message = deserialize(rustResponse.bytes) as Map;
var innerValue = message['after_number'] as int;
}
收到来自 Rust 的请求后,您应该首先按地址对它们进行分类。
pub async fn handle_request(request_unique: RustRequestUnique) -> RustResponseUnique {
let rust_request = request_unique.request;
let interaction_id = request_unique.id;
let layered: Vec<&str> = rust_request.address.split('.').collect();
let rust_response = if layered.is_empty() {
RustResponse::default()
} else if layered[0] == "basicCategory" {
if layered.len() == 1 {
RustResponse::default()
} else if layered[1] == "counterNumber" {
sample_functions::calculate_something(rust_request).await
} else {
RustResponse::default()
}
} else {
RustResponse::default()
};
RustResponseUnique {
id: interaction_id,
response: rust_response,
}
}
在 Rust 中处理请求如下。此处定义了终结点消息架构,因为它因地址和操作类型而异。
pub async fn calculate_something(rust_request: RustRequest) -> RustResponse {
match rust_request.operation {
Operation::Create => RustResponse::default(),
Operation::Read => {
#[allow(dead_code)]
#[derive(Deserialize)]
struct RustRequestSchema {
letter: String,
before_number: i32,
dummy_one: i32,
dummy_two: i32,
dummy_three: Vec<i32>,
}
let slice = rust_request.bytes.as_slice();
let received: RustRequestSchema = from_slice(slice).unwrap();
println!("{:?}", received.letter);
let before_value = received.before_number;
let after_value = sample_crate::add_seven(before_value);
#[derive(Serialize)]
struct RustResponseSchema {
after_number: i32,
dummy_one: i32,
dummy_two: i32,
dummy_three: Vec<i32>,
}
RustResponse {
successful: true,
bytes: to_vec_named(&RustResponseSchema {
after_number: after_value,
dummy_one: 1,
dummy_two: 2,
dummy_three: vec![3, 4, 5],
})
.unwrap(),
}
}
Operation::Update => RustResponse::default(),
Operation::Delete => RustResponse::default(),
}
}
您可以扩展此 RESTful API 模式,并根据需要创建成百上千个端点。如果您有 Web 背景,则此系统可能看起来很熟悉。更多的注释和细节包含在 Rust 模板内的实际代码中。
理想情况下,Flutter 将处理跨平台用户界面,而 Rust 处理业务逻辑。前端和后端可以完全分离,这意味着 Dart 和 Rust 代码可以相互分离。这两个世界通过channels 和streams进行通信。
使用 MessagePack 序列化 Rust 模板提供的在 Dart 和 Rust 之间发送的消息,除非您有其他原因不这样做。对于那些不熟悉的人来说,MessagePack 是一种类似于 JSON 的嵌套二进制结构,但更快、更高效。
在 Dart 和 Rust 之间发送的数据基本上是字节数组,表示为 Dart 和 Rust。尽管建议使用 MessagePack 序列化,但您可以根据需要发送任何类型的字节数据,例如高分辨率图像或某种文件数据。
与Flutter+Rust技术类似的,是ReactNative+Rust开发移动APP,参考相关说明[2];使用React开发的Electron跨平台桌面应用方式,可参考相关说明[3]。
References:
[1] rust_in_flutter | Flutter Package (pub.dev)
[2] 与Flutter+Rust技术类似的,是ReactNative+Rust开发移动APP:网址。
[3] 使用React开发的Electron跨平台桌面应用方式,参考wangzhi网址。