Rust
Lebenszeiten
Suche…
Syntax
- fn-Funktion <'a> (x: &' ein Typ)
- struct Struct <'a> {x: &' ein Typ}
- Aufzählung Aufzählung <'a> {Variante (&' ein Typ)}
- impl <'a> Struktur <' a> {fn x <'a> (& self) -> &' a Type {self.x}}
- impl <'a> Eigenschaft <' a> für Typ
- impl <'a> Eigenschaft für Typ <' a>
-
fn function<F>(f: F) where for<'a> F: FnOnce(&'a Type)
-
struct Struct<F> where for<'a> F: FnOnce(&'a Type) { x: F }
-
enum Enum<F> where for<'a> F: FnOnce(&'a Type) { Variant(F) }
-
impl<F> Struct<F> where for<'a> F: FnOnce(&'a Type) { fn x(&self) -> &F { &self.x } }
Bemerkungen
- Alle Verweise in Rust haben eine Lebensdauer, auch wenn sie nicht explizit kommentiert werden. Der Compiler kann Lebensdauern implizit zuweisen.
- Die
'static
Lebensdauer wird Referenzen zugewiesen, die in der Programmbinärdatei gespeichert sind, und ist während der gesamten Ausführung gültig. Diese Lebensdauer wird vor allem den String-Literalen zugewiesen, die den Typ&'static str
.
Funktionsparameter (Eingangslebensdauer)
fn foo<'a>(x: &'a u32) {
// ...
}
Dies gibt an, dass foo
die Lebensdauer 'a
hat und der Parameter x
eine Lebensdauer von mindestens 'a
. Funktionslebensdauern werden normalerweise durch die Laufzeitentscheidung weggelassen:
fn foo(x: &u32) {
// ...
}
In dem Fall , dass eine Funktion , mehrere Referenzen als Parameter und gibt eine Referenz nimmt, kann der Compiler nicht die Lebensdauer des Ergebnisses durch die Lebensdauer elision abzuleiten.
error[E0106]: missing lifetime specifier
1 | fn foo(bar: &str, baz: &str) -> &i32 {
| ^ expected lifetime parameter
Stattdessen sollten die Lebensdauerparameter explizit angegeben werden.
// Return value of `foo` is valid as long as `bar` and `baz` are alive.
fn foo<'a>(bar: &'a str, baz: &'a str) -> &'a i32 {
Funktionen können auch mehrere Lebensdauerparameter umfassen.
// Return value is valid for the scope of `bar`
fn foo<'a, 'b>(bar: &'a str, baz: &'b str) -> &'a i32 {
Strukturfelder
struct Struct<'a> {
x: &'a u32,
}
Dies gibt an, dass für eine gegebene Instanz von Struct
die Lebensdauer 'a
gilt und das in x
gespeicherte &u32
mindestens eine Lebensdauer von 'a
.
Impl-Blöcke
impl<'a> Type<'a> {
fn my_function(&self) -> &'a u32 {
self.x
}
}
Dies gibt an, dass Type
eine Lebenszeit 'a
hat und dass die von my_function()
Referenz nach 'a
endet möglicherweise nicht mehr gültig ist 'a
da der Type
nicht mehr für self.x
.
Höherrangige Eigenschaftsbegrenzungen
fn copy_if<F>(slice: &[i32], pred: F) -> Vec<i32>
where for<'a> F: Fn(&'a i32) -> bool
{
let mut result = vec![];
for &element in slice {
if pred(&element) {
result.push(element);
}
}
result
}
Dies gibt an, dass der Verweis auf i32 in der Fn
Eigenschaftsgrenze eine beliebige Lebensdauer haben kann.
Folgendes funktioniert nicht:
fn wrong_copy_if<'a, F>(slice: &[i32], pred: F) -> Vec<i32>
where F: Fn(&'a i32) -> bool
{ // <----------------+
let mut result = vec![]; // 'a scope |
for &element in slice { // <--------+ |
if pred(&element) { // | |
result.push(element); // element's| |
} // scope | |
} // <--------+ |
result // |
} // <----------------+
Der Compiler gibt den folgenden Fehler aus:
error: `element` does not live long enough
if pred(&element) { // | |
^~~~~~~
weil das element
lokale Variable lebt nicht so lange wie die 'a
Leben lang (wie wir aus dem Code der Kommentare sehen).
Die Lebensdauer kann nicht auf Funktionsebene deklariert werden, da wir eine andere Lebensdauer benötigen. Deshalb haben wir for<'a>
: um anzugeben, dass die Referenz für jede Lebensdauer gültig sein kann (daher kann eine kleinere Lebensdauer verwendet werden).
Höherrangige Merkmalsgrenzen können auch für Strukturen verwendet werden:
struct Window<F>
where for<'a> F: FnOnce(&'a Window<F>)
{
on_close: F,
}
sowie auf anderen Artikeln.
In den Fn*
-Merkmalen werden am häufigsten höhere Merkmalsgrenzen verwendet.
Für diese Beispiele funktioniert die Laufzeiteliminierung gut, so dass wir die Lebensdauer nicht angeben müssen.