Rust — ngôn ngữ lập trình hệ thống với đảm bảo an toàn bộ nhớ tại thời điểm biên dịch. Được phát triển bởi Mozilla Research vào năm 2010 dưới sự chỉ đạo của Graydon Hoare. Rust ngăn chặn toàn bộ các lớp lỗ hổng: con trỏ null, tham chiếu treo và điều kiện đua. Trong phát triển di động, Rust được sử dụng cho các mô-đun gốc, SDK đa nền tảng và WebAssembly. Theo Stack Overflow Survey (2025), Rust đứng đầu về «ngôn ngữ được yêu thích nhất» năm thứ chín liên tiếp.
Những điểm chính
Rust là ngôn ngữ lập trình hệ thống được định kiểu tĩnh với các trừu tượng không chi phí (zero-cost abstractions). Rust đảm bảo an toàn bộ nhớ không cần bộ thu gom rác nhờ hệ thống quyền sở hữu (ownership), vay mượn (borrowing) và thời gian sống (lifetimes). Trình biên dịch Rust là một trong những trình nghiêm ngặt nhất: nó từ chối mã mà trong C++ sẽ gây ra hành vi không xác định.
Rust biên dịch qua LLVM thành mã gốc cho tất cả kiến trúc: ARM, x86, RISC-V, WebAssembly. Bộ công cụ bao gồm: rustup (trình cài đặt), rustc (trình biên dịch), cargo (trình quản lý gói và xây dựng). Cargo.toml — tương tự package.json, chứa các phụ thuộc từ crates.io. Phiên bản ổn định mới nhất là Rust 1.81 (2025).
Các lĩnh vực ứng dụng chính của Rust trong phát triển di động: thư viện gốc (Android NDK, iOS), SDK đa nền tảng (Firefox, Dropbox), thay thế C++ trong các phần quan trọng về hiệu suất, WebAssembly cho ứng dụng lai. Google sử dụng Rust trong AOSP (Android Open Source Project) cho các thành phần Bluetooth, Wi-Fi và NFC.
Để biên dịch chéo cho Android, cần có chuỗi công cụ đích: rustup target add aarch64-linux-android armv7-linux-androideabi. Cho iOS — aarch64-apple-ios x86_64-apple-ios. cargo-ndk (cho Android) và cargo-lipo (cho iOS) đơn giản hóa quá trình xây dựng.
# Cài đặt Rust và nền tảng đích cho phát triển di động
$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
$ rustup target add aarch64-linux-android
$ rustup target add armv7-linux-androideabi
$ rustup target add aarch64-apple-ios
$ rustup target add x86_64-apple-ios
# Cài đặt cargo-ndk cho bản dựng Android
$ cargo install cargo-ndk
# Xây dựng cho Android
$ cargo ndk -t arm64-v8a -o ./jniLibs build --releaseOwnership (quyền sở hữu) là khái niệm nền tảng của Rust. Mỗi giá trị có chính xác một chủ sở hữu. Khi được gán hoặc truyền vào hàm, quyền sở hữu được di chuyển (move). Sau khi di chuyển, chủ sở hữu cũ không thể sử dụng giá trị. Điều này loại bỏ việc giải phóng bộ nhớ kép và con trỏ treo.
Borrowing (vay mượn) cho phép sử dụng tạm thời tham chiếu đến một giá trị mà không chuyển quyền sở hữu. Tham chiếu &T (bất biến) — số lượng người đọc không giới hạn. Tham chiếu &mut T (khả biến) — chính xác một người viết, không có người đọc. Trình biên dịch kiểm tra các quy tắc này tại thời điểm biên dịch.
fn process_data(data: &mut Vec<i32>) {
for item in data.iter_mut() {
*item *= 2;
}
}
fn main() {
let mut numbers = vec![1, 2, 3, 4, 5];
process_data(&mut numbers);
println!("Processed: {:?}", numbers);
let first = &numbers[0]; // vay mượn bất biến
println!("First: {}", first);
}process_data nhận một tham chiếu khả biến đến Vec và nhân đôi mỗi phần tử. iter_mut() trả về một trình vòng lặp với các tham chiếu khả biến. *item giải tham chiếu để gán. Sau process_data, numbers vẫn có thể truy cập — quyền sở hữu không bị chuyển, chỉ được mượn.
Lifetimes ('a) — chú thích liên kết thời gian sống của các tham chiếu. Trình biên dịch sử dụng chúng để xác minh rằng tham chiếu không tồn tại lâu hơn dữ liệu mà nó trỏ đến. Trong hầu hết các trường hợp, lifetimes được suy luận tự động — bạn chỉ cần chỉ định chúng trong chữ ký hàm có tham chiếu.
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() { x } else { y }
}
fn main() {
let string1 = String::from("rust");
let result;
{
let string2 = String::from("mobile");
result = longest(string1.as_str(), string2.as_str());
println!("Longest: {}", result);
} // string2 sống đến dấu ngoặc nhọn này, result hợp lệ bên trong
// println!("{}", result); // lỗi: string2 đã chết
}Rust biên dịch thành thư viện gốc cho Android (.so qua NDK) và iOS (.a thư viện tĩnh). Google chính thức hỗ trợ Rust trong Android Open Source Project (AOSP) — Rust được sử dụng cho các thành phần Bluetooth (ava), DNS-over-HTTP3 và CriticalNotification. Theo Google (2025), Rust trong Android đã loại bỏ 70% lỗ hổng bộ nhớ trong các thành phần mục tiêu.
Cho Android, cargo-ndk được sử dụng, nó bọc Cargo với chuỗi công cụ chính xác cho ABI đã chọn. Xây dựng cho Android bao gồm: aarch64-linux-android (ARM 64-bit, thiết bị hiện đại), armv7-linux-androideabi (ARM 32-bit), x86_64-linux-android (trình giả lập).
// Cargo.toml — cấu hình thư viện cho Android/iOS
[package]
name = "mobile_crypto"
version = "0.1.0"
[lib]
crate-type = ["staticlib", "cdylib"]
[dependencies]
serde = { version = "1", features = ["derive"] }
libc = "0.2"crate-type: staticlib — cho iOS (.a), cdylib — cho Android (.so). serde — tuần tự hóa để trao đổi dữ liệu với Kotlin/Swift. libc — kiểu tương thích C cho FFI.
use std::ffi::{CStr, CString};
use std::os::raw::c_char;
/// Hàm tương thích C để xử lý ảnh
#[no_mangle]
pub unsafe extern "C" fn process_image(
input: *const u8,
len: usize,
output: *mut u8,
out_len: *mut usize,
) {
let input_slice = std::slice::from_raw_parts(input, len);
let result: Vec<u8> = input_slice.iter()
.map(|b| b ^ 0xFF)
.collect();
let result_len = result.len();
std::ptr::copy_nonoverlapping(result.as_ptr(), output, result_len);
*out_len = result_len;
}#[no_mangle] vô hiệu hóa name mangling cho ABI tương thích C. extern "C" chỉ định quy ước gọi C. unsafe — điểm đánh dấu rằng việc gọi từ bên ngoài Rust không đảm bảo an toàn. std::ptr::copy_nonoverlapping sao chép byte kết quả vào bộ đệm đầu ra.
Rust là ứng cử viên lý tưởng cho SDK đa nền tảng hoạt động trên Android và iOS từ một mã nguồn duy nhất. Các công ty như Mozilla (Firefox), Dropbox (đồng bộ tệp) và Meta (blockchain Libra) đã chọn Rust cho các thành phần quan trọng trong ứng dụng di động của họ.
Lợi thế của thư viện Rust so với C++: trình biên dịch đảm bảo không có rò rỉ bộ nhớ và điều kiện đua trong mã đa nền tảng. Mã viết và kiểm thử trong Rust hoạt động giống hệt nhau trên tất cả nền tảng. Cargo quản lý phụ thuộc một cách gốc, không cần CMake hay vcpkg.
| Thư viện/Crate | Mục đích |
|---|---|
| tonic | Máy khách/máy chủ gRPC trong Rust |
| reqwest | Máy khách HTTP với async/await |
| ring | Mật mã học (AES, RSA, ECDSA) |
| sqlx | SQLite, PostgreSQL bất đồng bộ |
| wasm-bindgen | Tích hợp Rust với JavaScript/WASM |
| ndk-glue | Android NativeActivity trong Rust |
| uniffi | Tạo liên kết FFI cho Kotlin/Swift |
Rust biên dịch sang WebAssembly (Wasm) — định dạng nhị phân có thể thực thi trong trình duyệt và trên thiết bị di động. Wasm cung cấp hiệu suất gần như gốc trong môi trường web. Trong phát triển di động, Wasm được sử dụng trong ứng dụng lai (WebView + Wasm) cho các tính toán phức tạp: kết xuất 3D, nhận dạng ảnh, mã hóa.
wasm-pack biên dịch Rust thành .wasm và tạo trình bọc JS. wasm-bindgen kết nối các hàm Rust với lệnh gọi JavaScript. Trên thiết bị di động, trình chạy Wasm có thể chạy trong WebView hoặc qua SDK Wasmer/Wasmtime.
use wasm_bindgen::prelude::*;
/// Tính số Fibonacci trong Wasm (được gọi từ JS)
#[wasm_bindgen]
pub fn fibonacci(n: u32) -> u64 {
match n {
0 => 0,
1 => 1,
_ => {
let mut a = 0;
let mut b = 1;
for _ in 2..=n {
let temp = a + b;
a = b;
b = temp;
}
b
}
}
}#[wasm_bindgen] tạo trình bọc JavaScript cho hàm fibonacci. Trong trình duyệt, lệnh gọi trông như wasm.fibonacci(10). Các kiểu u32/u64 tự động chuyển đổi thành Number/BigInt. Mô-đun Wasm chỉ nặng ~5 KB cho một hàm như vậy — chi phí tối thiểu.
FFI (Foreign Function Interface) — cơ chế gọi mã Rust từ các ngôn ngữ khác. Các hàm Rust với extern "C" và #[no_mangle] được xuất với ABI tương thích C. Từ Kotlin, các hàm này được gọi qua JNI, từ Swift — qua @_cdecl ("name") hoặc CBridge.h.
UniFFI — công cụ Mozilla để tạo liên kết FFI. Bạn mô tả API trong tệp .udl và UniFFI tự động tạo trình bọc Kotlin và Swift. Đây là cách tiếp cận tiêu chuẩn cho các thành phần Rust trong Firefox Android và Firefox iOS.
// Thư viện Rust với giao diện UniFFI
uniffi::setup_scaffolding!();
#[derive(uniffi::Enum)]
pub enum EncryptionError {
InvalidKey,
EncryptionFailed,
}
#[derive(uniffi::Record)]
pub struct EncryptedData {
pub ciphertext: Vec<u8>,
pub nonce: Vec<u8>,
}
#[uniffi::export]
pub fn encrypt(key: &[u8], plaintext: &[u8]) -> Result<EncryptedData, EncryptionError> {
// triển khai AES-256-GCM
todo!()
}UniFFI tạo một lớp Kotlin với phương thức encrypt, nhận ByteArray và trả về EncryptedData. Trong Swift, một cấu trúc EncryptedData được tạo với các trường ciphertext (Data) và nonce (Data). Lỗi được chuyển đổi thành ngoại lệ Kotlin/Swift.
Rust và C++ là hai ngôn ngữ chính cho lập trình hệ thống trong phát triển di động. Cả hai đều biên dịch thành mã gốc ARM và hỗ trợ FFI qua ABI C. Sự khác biệt chính là mô hình an toàn bộ nhớ: Rust kiểm tra tại thời điểm biên dịch, C++ dựa vào kỷ luật của lập trình viên.
| Tiêu chí | Rust | C++ |
|---|---|---|
| An toàn bộ nhớ | Đảm bảo (ownership) | Trách nhiệm lập trình viên |
| Bộ thu gom rác | Không (RAII + ownership) | Không (quản lý thủ công) |
| Rò rỉ bộ nhớ | Trình biên dịch ngăn chặn | Có thể (new không delete) |
| Điều kiện đua | Ngăn chặn (Send + Sync) | Có thể |
| Android NDK | Qua cargo-ndk | Qua CMake / NDK Build |
| Hỗ trợ iOS | cargo-lipo + .a | Xcode + .a |
| Hệ thống xây dựng | Cargo (tích hợp) | CMake / Ninja |
| Thời gian xây dựng | 2–5 phút (sạch) | 5–15 phút (sạch) |
| Hệ sinh thái | crates.io (200k+ crates) | vcpkg / Conan (100k+ thư viện) |
Rust an toàn hơn C++ và năng suất hơn — trình biên dịch bắt lỗi mà trong C++ sẽ xuất hiện khi chạy. C++ có hệ sinh thái thư viện di động phong phú hơn. Cho dự án mới, Rust được ưu tiên; mã C++ hiện có được chuyển đổi dần dần.
Câu hỏi thường gặp
Sự khác biệt chính là an toàn bộ nhớ tại thời điểm biên dịch. Rust không có nullptr, con trỏ treo hay điều kiện đua nhờ hệ thống quyền sở hữu và borrow checker. C++ dựa vào kỷ luật lập trình viên, Rust dựa vào kiểm tra của trình biên dịch.
Có, qua Android NDK. Google chính thức hỗ trợ Rust trong AOSP (Android Open Source Project). Rust biên dịch thành thư viện .so qua cargo-ndk. FFI (Foreign Function Interface) qua JNI hoạt động giống như cho C++.
Cargo là trình quản lý gói và hệ thống xây dựng của Rust. Nó tải phụ thuộc từ crates.io, biên dịch dự án và chạy kiểm thử. Trong phát triển di động, cargo-ndk mở rộng Cargo để biên dịch chéo cho ABI Android.
Rust hỗ trợ cả hai nền tảng. Cho iOS, cargo-lipo được sử dụng để tạo tệp nhị phân phổ quát (arm64 + x86_64 trình giả lập). Mã Rust biên dịch thành thư viện tĩnh .a và được liên kết qua Xcode.
Có, Rust đang trở thành tiêu chuẩn cho SDK đa nền tảng và mô-đun gốc. Google, Meta và Mozilla đang đầu tư vào Rust. Cho các thành phần quan trọng về hiệu suất, Rust an toàn và năng suất hơn C++.
Tổng kết
Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay
IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.
Đọc thêm