2016-05-24 14 views
2

Ich versuche, Kennwörter und vertrauliche Daten aus der Systemumgebung zu laden, wenn mein Dienst gestartet wird. Ich habe eine Reihe verschiedener Möglichkeiten ausprobiert, aber ich habe nicht den richtigen Weg gefunden, dies in Rust zu tun.Füllen einer statischen/const mit einer Umgebungsvariablen zur Laufzeit in Rust

const PASSWORD: String = var("PASSWORD").unwrap(); 

Funktioniert nicht, weil method calls in constants are limited to constant inherent methods. Gleiches gilt für static (außer der Fehler sagt offensichtlich Statik).

Der andere Weg, den ich gesehen habe es

const PASSWORD: &'static str = env!("PASSWORD"); 

Aber das Problem mit diesem zu tun ist, ist, wird es bei der Kompilierung als env! ist ein Makro definiert werden (zumindest, dass mein Verständnis ist).

Ich dachte auch, einfach den Anruf auf var("...").unwrap() in einer Funktion zu wickeln, aber diese Lösung sitzt nicht wirklich richtig mit mir, und würde auch die Werte während der Laufzeit ändern UND nicht validieren sie beim Start des Dienstes.

Wie Sie feststellen können, bin ich neu in Rust. Ich würde wirklich schätzen, wenn Sie in Ihrer Antwort nicht erklären könnten, wie die const/static zur Laufzeit laden, sondern auch erklären, warum was ich mache dumm und falsch ist :)

Antwort

3

const und static füllen Sie verschiedene Rollen in Rust .

const bedeutet nicht nur eine Konstante, bedeutet dies einen Kompilierung- Konstante, einen Wert zur Compile-Zeit ermittelt und in dem Nur-Lese-Speicher des Programms eingeschrieben. Es ist nicht für Ihren Anwendungsfall geeignet.

static bedeutet eine globale Variable mit einer Lebensdauer, die das gesamte Programm umfasst. Es kann veränderbar sein, in diesem Fall muss es Sync sein, um gleichzeitige Änderungen zu vermeiden. Eine static Variable muss aus einer Konstanten initialisiert werden, um vom Start des Programms an verfügbar zu sein.

Also, wie eine Variable zur Laufzeit lesen und verfügbar haben? Nun, eine saubere Lösung wäre Globals insgesamt zu vermeiden ...

... aber da es bequem sein kann, gibt es eine Kiste dafür: lazy_static!.

lazy_static! { 
    static PASSWORD: String = var("PASSWORD").unwrap(); 
} 

Beim ersten Zugriff auf die Variable, wird der Ausdruck ausgeführt seinen Wert zu laden, wird der Wert dann bis zum Ende des Programms gespeichert und verfügbar ist.

+0

Gibt es einen besseren Weg? Ich würde es vorziehen, dass die Variablen geladen werden und ihre Anwesenheit zum Zeitpunkt des Starts validiert wird und nicht erst dann, wenn sie zum ersten Mal angefordert werden. Aber wenn Sie Globals nicht mögen, wie würden Sie sonst mit Umgebungsvariablen umgehen? Angenommen, sie würden sich nach dem Start des Services nicht ändern. Würde es irgendwo etwas Besseres geben, was ich tun könnte? – dave

+3

@dave: So werden Globals in Rust gehandhabt, greifen Sie einfach bei der ersten Gelegenheit (in main) zu und sie werden zum frühestmöglichen Zeitpunkt geladen. Wenn Sie Globals nicht verwenden, rufen Sie einfach das Passwort in einer Variablen ab und übergeben es dann (über Argumente) an alle, die es brauchen. Gleiche Funktionalität, aber es macht explizit, welcher Code-Block auf das Passwort zugreift. –

+0

Haha, fast zu einfach. Aber ja, ich sollte es wahrscheinlich so machen und ihre Anwesenheit bestätigen, während ich sie lade. Danke für die Einstellung der Klarheit. – dave