Rust — systemowy język programowania z gwarancjami bezpieczeństwa pamięci na etapie kompilacji. Opracowany przez Mozilla Research w 2010 roku pod kierownictwem Graydona Hoare'a. Rust zapobiega całym klasom podatności: wskaźnikom null, zwisającym referencjom i wyścigom danych. W programowaniu mobilnym Rust jest używany do modułów natywnych, wieloplatformowych SDK i WebAssembly. Według danych Stack Overflow Survey (2025), Rust zajmuje pierwsze miejsce jako „ulubiony język” dziewiąty rok z rzędu.
Najważniejsze
Rust — statycznie typowany język programowania systemowego z zerową abstrakcją (zero-cost abstractions). Rust gwarantuje bezpieczeństwo pamięci bez garbage collectora dzięki systemowi własności (ownership), pożyczania (borrowing) i czasów życia (lifetimes). Kompilator Rust jest jednym z najsurowszych — odrzuca kod, który w C++ spowodowałby niezdefiniowane zachowanie.
Rust kompiluje się przez LLVM do kodu natywnego dla wszystkich architektur: ARM, x86, RISC-V, WebAssembly. Narzędzia: rustup (instalator), rustc (kompilator), cargo (menedżer pakietów i narzędzie budowania). cargo.toml — odpowiednik package.json, zawiera zależności z crates.io. Aktualna wersja — Rust 1.81 (2025).
Kluczowe obszary zastosowania Rust w programowaniu mobilnym: biblioteki natywne (Android NDK, iOS), wieloplatformowe SDK (Firefox, Dropbox), zastąpienie C++ w sekcjach performance-critical, WebAssembly dla aplikacji hybrydowych. Google używa Rust w AOSP (Android Open Source Project) dla komponentów Bluetooth, Wi-Fi i NFC.
Do cross-kompilacji pod Android potrzebne są docelowe toolchainy: rustup target add aarch64-linux-android armv7-linux-androideabi. Dla iOS — aarch64-apple-ios x86_64-apple-ios. cargo-ndk (dla Androida) i cargo-lipo (dla iOS) upraszczają budowanie.
# Instalacja Rust i docelowych platform dla programowania mobilnego
$ 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
# Instalacja cargo-ndk dla budowania pod Android
$ cargo install cargo-ndk
# Budowanie pod Android
$ cargo ndk -t arm64-v8a -o ./jniLibs build --releaseOwnership (własność) — fundamentalne pojęcie Rust. Każda wartość ma dokładnie jednego właściciela. Przy przypisaniu lub przekazaniu do funkcji własność jest przenoszona (move). Po przeniesieniu stary właściciel nie może używać wartości. Eliminuje to podwójne zwalnianie pamięci i zwisające wskaźniki.
Borrowing (pożyczanie) umożliwia tymczasowe użycie referencji do wartości bez przenoszenia własności. Referencja &T (immutowalna) — dowolna liczba czytelników. Referencja &mut T (mutowalna) — dokładnie jeden pisarz, bez czytelników. Kompilator sprawdza te reguły na etapie budowania.
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!("Przetworzone: {:?}", numbers);
let first = &numbers[0]; // pożyczenie immutowalne
println!("Pierwszy: {}", first);
}process_data przyjmuje mutowalną referencję do Vec i podwaja każdy element. iter_mut() zwraca iterator z mutowalnymi referencjami. *item dereferencuje referencję do przypisania. Po process_data numbers pozostaje dostępny — własność nie została przeniesiona, tylko pożyczona.
Lifetimes ('a) — adnotacje do wiązania czasów życia referencji. Kompilator używa ich do sprawdzenia, czy referencja nie przeżywa danych, na które wskazuje. W większości przypadków lifetimes są wyprowadzane automatycznie — należy je podawać tylko w sygnaturach funkcji z referencjami.
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!("Najdłuższy: {}", result);
} // string2 żyje do tego nawiasu, result jest ważny wewnątrz
// println!("{}", result); // błąd: string2 umarł
}Rust kompiluje się do bibliotek natywnych dla Androida (.so przez NDK) i iOS (.a biblioteki statyczne). Google oficjalnie wspiera Rust w Android Open Source Project (AOSP) — w Rust napisano komponenty Bluetooth (ava), DNS-over-HTTP3 i CriticalNotification. Według Google (2025), Rust w Android wyeliminował 70% podatności pamięci w docelowych komponentach.
Dla Androida używany jest cargo-ndk, który opakowuje Cargo z odpowiednim toolchainem dla wybranego ABI. Budowanie pod Android obejmuje: aarch64-linux-android (64-bit ARM, nowoczesne urządzenia), armv7-linux-androideabi (32-bit ARM), x86_64-linux-android (emulatory).
// Cargo.toml — konfiguracja biblioteki dla 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 — dla iOS (.a), cdylib — dla Androida (.so). serde — serializacja do wymiany danych z Kotlin/Swift. libc — typy C-kompatybilne dla FFI.
use std::ffi::{CStr, CString};
use std::os::raw::c_char;
/// Funkcja C-kompatybilna do przetwarzania obrazu
#[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] wyłącza name mangling dla C-kompatybilnego ABI. extern "C" ustawia konwencję wywoływania C. unsafe — znacznik, że wywołanie spoza Rust nie gwarantuje bezpieczeństwa. std::ptr::copy_nonoverlapping kopiuje bajty wyniku do bufora wyjściowego.
Rust — idealny kandydat na wieloplatformowe SDK działające na Android i iOS z jednej bazy kodu. Firmy Mozilla (Firefox), Dropbox (synchronizacja plików) i Meta (Libra blockchain) wybrały Rust do krytycznych komponentów swoich aplikacji mobilnych.
Zalety biblioteki Rust w porównaniu z C++: kompilator gwarantuje brak wycieków pamięci i wyścigów danych w kodzie wieloplatformowym. Kod w Rust napisany raz i przetestowany działa identycznie na wszystkich platformach. Cargo zarządza zależnościami natywnie, bez CMake i vcpkg.
| Biblioteka/Krata | Przeznaczenie |
|---|---|
| tonic | gRPC klient/serwer w Rust |
| reqwest | Klient HTTP z async/await |
| ring | Kryptografia (AES, RSA, ECDSA) |
| sqlx | Asynchroniczna praca z SQLite, PostgreSQL |
| wasm-bindgen | Integracja Rust z JavaScript/WASM |
| ndk-glue | Android NativeActivity w Rust |
| uniffi | Generowanie wiązań FFI dla Kotlin/Swift |
Rust kompiluje się do WebAssembly (Wasm) — formatu binarnego wykonywalnego w przeglądarce i na urządzeniach mobilnych. Wasm zapewnia wydajność near-native w środowisku webowym. W programowaniu mobilnym Wasm jest używany w aplikacjach hybrydowych (WebView + Wasm) do złożonych obliczeń: renderowanie 3D, rozpoznawanie obrazów, szyfrowanie.
wasm-pack kompiluje Rust do .wasm i generuje opakowanie JS. wasm-bindgen łączy funkcje Rust z wywołaniami JavaScript. Na urządzeniu mobilnym Wasm-runner może działać w WebView lub przez SDK Wasmer/Wasmtime.
use wasm_bindgen::prelude::*;
/// Obliczanie liczby Fibonacciego w Wasm (wywoływane z 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] generuje opakowanie JavaScript dla funkcji fibonacci. W przeglądarce wywołanie wygląda jak wasm.fibonacci(10). Typy u32/u64 są automatycznie konwertowane na Number/BigInt. Moduł Wasm waży ~5 KB dla takiej funkcji — minimalny narzut.
FFI (Foreign Function Interface) — mechanizm wywoływania kodu Rust z innych języków. Funkcje Rust z extern "C" i #[no_mangle] są eksportowane z C-kompatybilnym ABI. Z Kotlin takie funkcje są wywoływane przez JNI, ze Swift — przez @_cdecl ("name") lub CBridge.h.
UniFFI — narzędzie Mozilla do generowania wiązań FFI. Opisujesz API w pliku .udl, UniFFI generuje opakowania Kotlin i Swift automatycznie. To standardowe podejście dla komponentów Rust w Firefox Android i Firefox iOS.
// Biblioteka Rust z interfejsem 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> {
// implementacja AES-256-GCM
todo!()
}UniFFI generuje klasę Kotlin z metodą encrypt, przyjmującą ByteArray i zwracającą EncryptedData. W Swift tworzona jest struktura EncryptedData z polami ciphertext (Data) i nonce (Data). Błędy są przekształcane w wyjątki Kotlin/Swift.
Rust i C++ — dwa główne języki programowania systemowego w programowaniu mobilnym. Oba kompilują się do kodu natywnego dla ARM i obsługują FFI przez C ABI. Główna różnica — model bezpieczeństwa pamięci: Rust sprawdza go na etapie kompilacji, C++ polega na dyscyplinie programisty.
| Kryterium | Rust | C++ |
|---|---|---|
| Bezpieczeństwo pamięci | Gwarantowane (ownership) | Odpowiedzialność programisty |
| Garbage collector | Nie (RAII + ownership) | Nie (ręczne zarządzanie) |
| Wycieki pamięci | Zapobiegane przez kompilator | Możliwe (new bez delete) |
| Wyścigi danych | Zapobiegane (Send + Sync) | Możliwe |
| Android NDK | Przez cargo-ndk | Przez CMake / NDK Build |
| Wsparcie iOS | cargo-lipo + .a | Xcode + .a |
| Budowanie | Cargo (wbudowany) | CMake / Ninja |
| Czas budowania | 2–5 min (clean) | 5–15 min (clean) |
| Ekosystem | crates.io (200k+ krat) | vcpkg / Conan (100k+ bibliotek) |
Rust jest bezpieczniejszy niż C++ i bardziej produktywny — kompilator łapie błędy, które w C++ ujawniłyby się w czasie wykonania. C++ ma bogatszy ekosystem bibliotek mobilnych. Dla nowych projektów Rust jest preferowany; istniejący kod C++ jest portowany stopniowo.
Często zadawane pytania
Główna różnica — bezpieczeństwo pamięci na etapie kompilacji. W Rust nie ma nullptr, zwisających wskaźników i wyścigów danych dzięki systemowi własności (ownership) i borrow checker. C++ polega na dyscyplinie programisty, Rust — na kontrolach kompilatora.
Tak, przez Android NDK. Google oficjalnie wspiera Rust w AOSP (Android Open Source Project). Rust kompiluje się do bibliotek .so przez cargo-ndk. FFI (Foreign Function Interface) przez JNI działa tak samo jak dla C++.
Cargo — menedżer pakietów i system budowania Rust. Pobiera zależności z crates.io, kompiluje projekt i uruchamia testy. W programowaniu mobilnym cargo-ndk rozszerza Cargo o cross-kompilację dla Android ABI.
Rust obsługuje obie platformy. Dla iOS używany jest cargo-lipo do uniwersalnych binarek (arm64 + x86_64 symulator). Kod Rust kompiluje się do biblioteki statycznej .a i linkuje przez Xcode.
Tak, Rust staje się standardem dla wieloplatformowych SDK i modułów natywnych. Google, Meta i Mozilla inwestują w Rust. Dla komponentów performance-critical Rust jest bezpieczniejszy i bardziej produktywny niż C++.
Podsumowanie
Opracujemy aplikację mobilną pod klucz
IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.
Przeczytaj również