Rust у мобільній розробці: нативні модулі та кроссплатформенні SDK

Автор: IT Sectr Опубліковано: 2026-02-11 Час читання: 10 хв

Rust — системна мова програмування з гарантіями безпеки пам'яті на етапі компіляції. Розроблена Mozilla Research у 2010 році під керівництвом Грейдона Хора. Rust запобігає цілим класам вразливостей: null-покажчики, висячі посилання та стани гонитви. У мобільній розробці Rust використовується для нативних модулів, кроссплатформенних SDK та WebAssembly. За даними Stack Overflow Survey (2025), Rust займає перше місце за «найулюбленішою мовою» дев'ятий рік поспіль.

Головне

  • Rust — системна мова з безпекою пам'яті без збирача сміття через систему володіння (ownership)
  • Borrow checker — аналізатор позик, що перевіряє посилання на етапі компіляції, запобігаючи станам гонитви
  • Нативні модулі на Rust компілюються в .so для Android та .a для iOS через cargo-ndk та cargo-lipo
  • WebAssembly (Wasm) дозволяє запускати код Rust у браузері та на мобільних пристроях з продуктивністю near-native
  • FFI (Foreign Function Interface) — механізм виклику Rust з Java, Kotlin та Swift через C-сумісний ABI

Що таке Rust?

Rust — статично типізована мова системного програмування з нульовою абстракцією (zero-cost abstractions). Rust гарантує безпеку пам'яті без збирача сміття завдяки системі володіння (ownership), позичання (borrowing) та часу життя (lifetimes). Компілятор Rust — один з найсуворіших: він відхиляє код, який у C++ викликав би невизначену поведінку.

Rust компілюється через LLVM у нативний код для всіх архітектур: ARM, x86, RISC-V, WebAssembly. Інструментарій: rustup (встановлювач), rustc (компілятор), cargo (менеджер пакунків та збирач). Cargo.toml — аналог package.json, містить залежності з crates.io. Актуальна стабільна версія — Rust 1.81 (2025).

Ключові сфери застосування Rust у мобільній розробці: нативні бібліотеки (Android NDK, iOS), кроссплатформенні SDK (Firefox, Dropbox), заміна C++ у performance-critical ділянках, WebAssembly для гібридних додатків. Google використовує Rust у AOSP (Android Open Source Project) для компонентів Bluetooth, Wi-Fi та NFC.

Встановлення та налаштування Rust для мобільної розробки

Для крос-компіляції під Android потрібні цільові тулчейни: rustup target add aarch64-linux-android armv7-linux-androideabi. Для iOS — aarch64-apple-ios x86_64-apple-ios. cargo-ndk (для Android) та cargo-lipo (для iOS) спрощують збірку.

sh
# Встановлення Rust та цільових платформ для мобільної розробки
$ 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

# Встановлення cargo-ndk для Android збірки
$ cargo install cargo-ndk

# Збірка під Android
$ cargo ndk -t arm64-v8a -o ./jniLibs build --release

Система володіння: ownership, borrowing та lifetimes

Ownership (володіння) — фундаментальне поняття Rust. Кожне значення має рівно одного власника. При присвоєнні або передачі в функцію володіння переміщується (move). Після переміщення старий власник не може використовувати значення. Це виключає подвійне звільнення пам'яті та висячі покажчики.

Borrowing (позичання) дозволяє тимчасово використовувати посилання на значення без передачі володіння. Посилання &T (незмінне) — скільки завгодно читачів. Посилання &mut T (змінне) — рівно один письменник, без читачів. Компілятор перевіряє ці правила на етапі збірки.

rust
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];  // незмінне позичання
    println!("First: {}", first);
}

process_data приймає змінне посилання на Vec і подвоює кожен елемент. iter_mut() повертає ітератор зі змінними посиланнями. *item розіменовує посилання для присвоєння. Після process_data numbers залишається доступним — володіння не переміщувалося, тільки позичання.

Lifetimes: час життя посилань

Lifetimes ('a) — анотації для зв'язування часів життя посилань. Компілятор використовує їх для перевірки, що посилання не переживає дані, на які вказує. У більшості випадків lifetimes виводяться автоматично — вказувати їх потрібно лише в сигнатурах функцій із посиланнями.

rust
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 живе до цієї дужки, result валідний всередині
    // println!("{}", result); // помилка: string2 помер
}

Rust для нативних модулів Android та iOS

Rust компілюється в нативні бібліотеки для Android (.so через NDK) та iOS (.a статичні бібліотеки). Google офіційно підтримує Rust у Android Open Source Project (AOSP) — на Rust написані компоненти Bluetooth (ava), DNS-over-HTTP3 та CriticalNotification. За даними Google (2025), Rust в Android усунув 70% вразливостей пам'яті в цільових компонентах.

Для Android використовується cargo-ndk, який обгортає Cargo з правильним тулчейном для вибраного ABI. Збірка під Android включає: aarch64-linux-android (64-bit ARM, сучасні пристрої), armv7-linux-androideabi (32-bit ARM), x86_64-linux-android (емулятори).

rust
// Cargo.toml — конфігурація бібліотеки для 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 — для iOS (.a), cdylib — для Android (.so). serde — серіалізація для обміну даними з Kotlin/Swift. libc — C-сумісні типи для FFI.

Приклад: обробка зображення на Rust

rust
use std::ffi::{CStr, CString};
use std::os::raw::c_char;

/// C-сумісна функція для обробки зображення
#[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] вимикає name mangling для C-сумісного ABI. extern "C" задає C-конвенцію виклику. unsafe — маркер, що виклик ззовні Rust не гарантує безпеку. std::ptr::copy_nonoverlapping копіює байти результату в вихідний буфер.

Кроссплатформенні SDK на Rust

Rust — ідеальний кандидат для кроссплатформенних SDK, що працюють на Android та iOS з однієї кодової бази. Компанії Mozilla (Firefox), Dropbox (синхронізація файлів) та Meta (Libra blockchain) обрали Rust для критичних компонентів своїх мобільних додатків.

Переваги Rust-бібліотеки перед C++: компілятор гарантує відсутність витоків пам'яті та станів гонитви в кроссплатформенному коді. Код на Rust один раз написаний і протестований — працює однаково на всіх платформах. Cargo керує залежностями нативно, без CMake та vcpkg.

Бібліотека/КрейтПризначення
tonicgRPC клієнт/сервер на Rust
reqwestHTTP-клієнт з async/await
ringКриптографія (AES, RSA, ECDSA)
sqlxАсинхронна робота з SQLite, PostgreSQL
wasm-bindgenІнтеграція Rust з JavaScript/WASM
ndk-glueAndroid NativeActivity на Rust
uniffiГенерація FFI-прив'язок для Kotlin/Swift

Rust та WebAssembly для мобільних додатків

Rust компілюється в WebAssembly (Wasm) — бінарний формат, виконуваний у браузері та на мобільних пристроях. Wasm забезпечує продуктивність near-native у веб-середовищі. У мобільній розробці Wasm використовується в гібридних додатках (WebView + Wasm) для складних обчислень: 3D-рендеринг, розпізнавання образів, шифрування.

wasm-pack компілює Rust у .wasm та генерує JS-обгортку. wasm-bindgen пов'язує Rust-функції з JavaScript-викликами. На мобільному пристрої Wasm-runner може запускатися в WebView або через Wasmer/Wasmtime SDK.

rust
use wasm_bindgen::prelude::*;

/// Обчислення числа Фібоначчі в Wasm (викликається з 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] генерує JavaScript-обгортку для функції fibonacci. У браузері виклик виглядає як wasm.fibonacci(10). Типи u32/u64 автоматично конвертуються в Number/BigInt. Wasm-модуль важить ~5 КБ для такої функції — мінімальний overhead.

FFI: виклик Rust з Kotlin та Swift

FFI (Foreign Function Interface) — механізм виклику коду Rust з інших мов. Функції Rust з extern "C" та #[no_mangle] експортуються з C-сумісним ABI. З Kotlin такі функції викликаються через JNI, з Swift — через @_cdecl ("name") або CBridge.h.

UniFFI — інструмент Mozilla для генерації FFI-прив'язок. Описуєте API в .udl-файлі, UniFFI генерує обгортки Kotlin та Swift автоматично. Це стандартний підхід для Rust-компонентів у Firefox Android та Firefox iOS.

rust
// Бібліотека на Rust з інтерфейсом 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> {
    // реалізація AES-256-GCM
    todo!()
}

UniFFI генерує клас Kotlin з методом encrypt, що приймає ByteArray та повертає EncryptedData. У Swift створюється структура EncryptedData з полями ciphertext (Data) та nonce (Data). Помилки перетворюються на винятки Kotlin/Swift.

Rust проти C++: порівняння для мобільної розробки

Rust та C++ — дві основні мови для системного програмування в мобільній розробці. Обидві компілюються в нативний код для ARM та підтримують FFI через C ABI. Головна відмінність — модель безпеки пам'яті: Rust перевіряє її на етапі компіляції, C++ покладається на дисципліну розробника.

КритерійRustC++
Безпека пам'ятіГарантована (ownership)Відповідальність розробника
Збирач сміттяНемає (RAII + ownership)Немає (ручне керування)
Витоки пам'ятіЗапобігаються компіляторомМожливі (new без delete)
Стани гонитвиЗапобігаються (Send + Sync)Можливі
Android NDKЧерез cargo-ndkЧерез CMake / NDK Build
Підтримка iOScargo-lipo + .aXcode + .a
Система збіркиCargo (вбудований)CMake / Ninja
Час збірки2–5 хв (clean)5–15 хв (clean)
Екосистемаcrates.io (200k+ крейтів)vcpkg / Conan (100k+ бібліотек)

Rust безпечніший за C++ та продуктивніший — компілятор ловить помилки, які в C++ проявилися б у рантаймі. C++ має багатшу екосистему мобільних бібліотек. Для нових проєктів Rust переважніший; існуючий C++-код портують поступово.

Часто задавані питання

Чим Rust відрізняється від C++ для мобільної розробки?

Головна відмінність — безпека пам'яті на етапі компіляції. У Rust немає nullptr, висячих покажчиків та станів гонитви завдяки системі володіння (ownership) та borrow checker. C++ покладається на дисципліну розробника, Rust — на перевірки компілятора.

Rust можна використовувати в Android розробці?

Так, через Android NDK. Google офіційно підтримує Rust у AOSP (Android Open Source Project). Rust компілюється в .so бібліотеки через cargo-ndk. FFI (Foreign Function Interface) через JNI працює так само, як для C++.

Що таке cargo і як він допомагає в розробці на Rust?

Cargo — менеджер пакунків та система збірки Rust. Він завантажує залежності з crates.io, компілює проєкт та запускає тести. У мобільній розробці cargo-ndk розширює Cargo для крос-компіляції під Android ABI.

Rust підходить для iOS чи тільки Android?

Rust підтримує обидві платформи. Для iOS використовується cargo-lipo для універсальних бінарників (arm64 + x86_64 симулятор). Код Rust компілюється в статичну бібліотеку .a та лінкується через Xcode.

Чи варто вивчати Rust для мобільної розробки у 2026 році?

Так, Rust стає стандартом для кроссплатформенних SDK та нативних модулів. Google, Meta та Mozilla інвестують у Rust. Для performance-critical компонентів Rust безпечніший та продуктивніший за C++.

Підсумки

  • Rust — системна мова з безпекою пам'яті без GC завдяки ownership, borrowing та lifetimes
  • Borrow checker запобігає станам гонитви та висячим покажчикам на етапі компіляції
  • Нативні модулі збираються через cargo-ndk (Android .so) та cargo-lipo (iOS .a)
  • UniFFI генерує FFI-прив'язки для Kotlin та Swift — стандарт Mozilla для мобільних SDK
  • WebAssembly дозволяє запускати Rust у мобільних WebView з near-native продуктивністю
  • Google використовує Rust в AOSP — на 70% скоротилися вразливості пам'яті в цільових компонентах
  • Rust vs C++: Rust безпечніший, C++ — з багатшою екосистемою; для нових нативних модулів обирають Rust

Ми розробимо мобільний застосунок під ключ

IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.

Обговорити проект

Читайте також