Ответ 1
Отказ от ответственности: я не являюсь именно гуру CS, поэтому этот ответ будет посвящен практическим концепциям, и я даже не попытаюсь связать его с теоретическими концепциями, чтобы я не делал беспорядок.
Я думаю, что проблема заключается в применении концепции подтипирования к тому, что не является типом.
-
'a
- это время жизни -
&'a T
- это тип
Вы можете сравнить &'a T
и &'b U
и посмотреть, подчиняются ли они отношениям подтипирования, но вы не можете установить отношение субтипирования с двумя временами жизни в реферате, потому что:
- иногда, чтобы быть подставляемым, новое время жизни должно быть больше, чем замененное время жизни.
- иногда, чтобы быть подставляемым, новое время жизни должно быть меньше, чем замененное время жизни.
Мы можем проверить это на двух простых примерах.
Первый пример, возможно, самый простой: срок жизни может быть заменен, если он больше!
// Using a lifetime as a bound
struct Reference<'a, T>
where T: 'a
{
data: &'a T
}
fn switch<'a, 'b, T>(r: &mut Reference<'a, T>, new: &'b T)
where 'b: 'a
{
r.data = new;
}
Здесь компилятор разрешает замену, если 'b
не меньше, чем 'a
, которое выражается привязкой времени жизни 'b: 'a
. Это связано с тем, что Rust не терпит болтающих ссылок, и, таким образом, контейнер может содержать только ссылки на объекты, которые оживят его.
При использовании в качестве гарантии большее время жизни является подтипом меньшего времени жизни и может быть заменено вместо него. Эти намеки, как упоминалось в @aturon, что в этом использовании 'static
является подтипом всех времен жизни.
Второй пример немного сложнее: срок жизни может быть заменен, если он меньше!
Начнем со следующего:
struct Token;
fn restrict<'a, 'b, T>(original: &'a T, _: &'b Token) -> &'b T
where 'a: 'b
{
original
}
Правильное использование:
fn main() {
let i = 4;
{
let lesser = Token;
let k = restrict(&i, &lesser);
println!("{}", k);
}
}
И наша предыдущая демонстрация заявила, что мы можем заменить большее время жизни вместо меньшего:
fn main() {
let greater = Token;
let j; // prevent unification of lifetimes
{
let i = 4;
j = restrict(&i, &greater);
}
println!("{}", j);
}
error: `i` does not live long enough
j = restrict(&i, &greater);
При использовании в качестве ограничения меньшее время жизни является подтипом большего времени жизни и может быть заменено вместо него. В этом использовании 'static
является супертипом всех времен жизни.
Следовательно, нет единственного отношения подтипирования между сроками жизни, потому что они служат двум радикально противоположным целям!
Повторить:
- при использовании в качестве гарантии:
greater <: lesser
- при использовании в качестве ограничения:
lesser <: greater
Примечание. Некоторое время жизни может правдоподобно действовать как гарантия и ограничение одновременно.