Rust
Время жизни
Поиск…
Синтаксис
- fn функция <'a> (x: &' a Тип)
- struct Struct <'a> {x: &' a Тип}
- enum Enum <'a> {Вариант (&' a Тип)}
- impl <'a> Struct <' a> {fn x <'a> (& self) -> &' a Type {self.x}}
- impl <'a> Значение <' a> для типа
- impl <'a> Trait для Type <' 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 } }
замечания
- Все ссылки в Rust имеют всю жизнь, даже если они явно не аннотируются. Компилятор способен неявно назначать сроки жизни.
-
'static
время жизни назначается для ссылок, которые хранятся в двоичном коде программы и будут действительны на протяжении всего его выполнения. Это время жизни больше всего относится к строковым литералам, которые имеют тип&'static str
.
Параметры функции (время ввода)
fn foo<'a>(x: &'a u32) {
// ...
}
Это указывает на то, что foo
имеет время жизни 'a
, а параметр x
должен иметь время жизни не менее 'a
. Функциональные времена жизни обычно пропускаются по времени жизни :
fn foo(x: &u32) {
// ...
}
В случае, когда функция принимает несколько ссылок в качестве параметров и возвращает ссылку, компилятор не может вывести время жизни результата через пожизненный elision .
error[E0106]: missing lifetime specifier
1 | fn foo(bar: &str, baz: &str) -> &i32 {
| ^ expected lifetime parameter
Вместо этого параметры срока жизни должны быть явно указаны.
// 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 {
Функции также могут принимать несколько параметров времени жизни.
// Return value is valid for the scope of `bar`
fn foo<'a, 'b>(bar: &'a str, baz: &'b str) -> &'a i32 {
Поля структуры
struct Struct<'a> {
x: &'a u32,
}
Это указывает, что любой данный экземпляр Struct
имеет время жизни 'a
, а &u32
хранящийся в x
должен иметь время жизни не менее 'a
.
Блокировка Impl
impl<'a> Type<'a> {
fn my_function(&self) -> &'a u32 {
self.x
}
}
Это указывает, что Type
имеет время жизни 'a
и что ссылка, возвращаемая my_function()
может быть более недействительной после того, как 'a
заканчивается, потому что Type
больше не существует для сохранения self.x
Границы уровня более высокого ранга
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
}
Это указывает, что ссылка на i32 в привязке к значению Fn
может иметь любое время жизни.
Не работает следующее:
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 // |
} // <----------------+
Компилятор дает следующую ошибку:
error: `element` does not live long enough
if pred(&element) { // | |
^~~~~~~
потому что локальная переменная element
не живет так долго, как 'a
жизни» (как мы видим из комментариев кода).
Время жизни не может быть объявлено на уровне функции, потому что нам нужно другое время жизни. Вот почему мы использовали for<'a>
: чтобы указать, что ссылка может быть действительной для любого времени жизни (следовательно, можно использовать меньшее время жизни).
Оценки границ более высокого ранга также могут быть использованы для структур:
struct Window<F>
where for<'a> F: FnOnce(&'a Window<F>)
{
on_close: F,
}
а также на другие предметы.
Оценки признаков более высокого ранга наиболее часто используются с чертами Fn*
.
Для этих примеров время жизни elision работает нормально, поэтому нам не нужно указывать сроки жизни.