Internationalisierung von Rust-Anwendungen: Von Null zu Mehrsprachigkeit

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Warum Ihre Rust-Anwendung Internationalisierung braucht (und wie Sie es nicht vermasseln)

\n\n

Sie haben den perfekten Parser in Rust geschrieben. Er fliegt schneller als der Blitz und verbraucht weniger Speicher als eine bescheidene Kohlmeise. Aber es gibt ein Problem: Ihr Text wird nur auf Englisch ausgegeben. Und Benutzer aus Tokio, Berlin und Sankt Petersburg möchten die Oberfläche in ihrer Muttersprache sehen.

\n\n

Internationalisierung (i18n) ist nicht nur das "Übersetzen von Schaltflächen". Es ist eine architektonische Entscheidung, die Ihren Code in einen eleganten Konstrukteur oder eine höllische Ansammlung von if-else-Anweisungen verwandeln kann. In diesem Artikel werden wir analysieren, wie man Internationalisierung in Rust richtig macht: ohne Schmerzen, mit Beispielen und mit Respekt für das Gehirn des zukünftigen Entwicklers (Ihres).

\n\n

Wir werden über zwei leistungsstarke Ansätze sprechen: die fluent-Bibliothek (Empfehlung von Mozilla) und das klassische rust-i18n, das auf gettext basiert. Am Ende des Artikels werden Sie in der Lage sein, in 15 Minuten Unterstützung für Russisch, Englisch und jede andere Sprache zu Ihrem Tool hinzuzufügen.

\n\n

Schlachtplan: Was sind i18n und l10n in der Rust-Welt

\n\n

Bevor wir in den Code eintauchen, lassen Sie uns die Begriffe klären:

\n
    \n
  • Internationalisierung (i18n) — Vorbereiten des Codes für die Übersetzung. Sie extrahieren alle Zeichenfolgen in separate Dateien und bringen dem Programm bei, das erforderliche Gebietsschema zu laden.
  • \n
  • Lokalisierung (l10n) — die Übersetzung selbst. Erstellen von Dateien für jede Sprache.
  • \n
  • Gebietsschema (Locale) — eine Kombination aus Sprache und Region (z. B. ru-RU, en-US, de-DE).
  • \n
\n\n

In Rust gibt es mehrere Wege. Wir werden uns die beiden beliebtesten ansehen:

\n
    \n
  • Fluent — ein modernes System von Mozilla. Leistungsstark, flexibel, mit Unterstützung für Pluralbildung und Kontext.
  • \n
  • rust-i18n — Makros, inspiriert von Ruby on Rails. Einfacher, aber weniger flexibel.
  • \n
\n\n

Die Wahl hängt von der Aufgabe ab. Für CLI-Dienstprogramme ist rust-i18n ausreichend. Für Webanwendungen oder komplexe GUIs (z. B. auf Tauri) ist es besser, Fluent zu verwenden.

\n\n

Methode #1: Rust-Internationalisierung mit Fluent (Professioneller Ansatz)

\n\n

Installieren und Konfigurieren von Fluent

\n\n

Lassen Sie uns ein neues Projekt erstellen und Abhängigkeiten hinzufügen:

\n\n
cargo new i18n_demo\ncd i18n_demo\ncargo add fluent fluent-bundle fluent-langtag unic-langid\n
\n\n

Die Dateistruktur wird wie folgt aussehen:

\n\n
projekt/\n├── Cargo.toml\n├── locales/\n│   ├── ru/\n│   │   └── main.ftl\n│   └── en/\n│       └── main.ftl\n└── src/\n    └── main.rs\n
\n\n

Erstellen von Lokalisierungsdateien (FTL)

\n\n

Fluent verwendet das FTL-Format (Fluent Translation List). Es ist sauber und leistungsstark:

\n\n

locales/en/main.ftl:

\n
greeting = Hello, { $name }!\ngoodbye = Goodbye\napples = { $count ->\n    [one] { $count } apple\n    [few] { $count } apples\n    *[other] { $count } apples\n}\n
\n\n

locales/ru/main.ftl:

\n
greeting = Привет, { $name }!\ngoodbye = До свидания\napples = { $count ->\n    [one] { $count } яблоко\n    [few] { $count } яблока\n    [many] { $count } яблок\n    *[other] { $count } яблок\n}\n
\n\n

Beachten Sie die Pluralbildung. Im Russischen gibt es vier Formen (eins, zwei-vier, fünf-zwanzig, der Rest), während es im Englischen zwei gibt (eins, der Rest). Fluent verarbeitet dies automatisch.

\n\n

Schreiben von Rust-Code zum Laden von Gebietsschemata

\n\n

Jetzt der interessante Teil — der Code, der die gewünschte Sprache basierend auf dem System des Benutzers auswählt:

\n\n
use fluent_bundle::{FluentBundle, FluentResource};\nuse unic_langid::LanguageIdentifier;\nuse std::fs;\nuse std::path::Path;\n\nfn load_locale(locale: &str) -> FluentBundle<FluentResource> {\n    let langid: LanguageIdentifier = locale.parse().expect("Invalid locale");\n    let mut bundle = FluentBundle::new(vec![langid]);\n\n    let file_path = format!("locales/{}/main.ftl", locale);\n    let source = fs::read_to_string(&file_path)\n        .expect(&fo                

Blogs

Buchempfehlungen