Я пытаюсь выучить правила жизни Rust, сравнивая их с аналогичными понятиями в C ++, с которыми я больше знаком.Большую часть времени моя интуиция работает очень хорошо, и я могу понять смысл правила.Однако в следующем случае я не уверен, правильно ли я понимаю.
В Rust время жизни временного значения - это конец его оператора, за исключением случаев, когда последнее временное значение связано симя с использованием let
.
struct A(u8);
struct B(u8);
impl A {
fn get_b(&mut self) -> Option<B> {
Some(B(self.0))
}
}
fn a(v: u8) -> A {
A(v)
}
// temporary A's lifetime is the end of the statement
// temporary B binds to a name so lives until the enclosing block
let b = a(1).get_b();
// temporary A's lifetime is the end of the statement
// temporary B's lifetime extends to the enclosing block,
// so that taking reference of temporary works similar as above
let b = &a(2).get_b();
Если временное значение находится в состоянии if
, то согласно ссылке время жизни ограничивается условным выражением.
// Both temporary A and temporary B drops before printing some
if a(3).get_b().unwrap().val <= 3 {
println!("some");
}
Теперь к вопросу:
Если поместить let
в if
условие, из-за сопоставления с образцом мы привязываемся к внутренней части временного значения.Я ожидал бы, что временное значение, ограниченное let
, будет расширено на вмещающий блок, в то время как другие временные значения все еще должны иметь время жизни, ограниченное условием if.
(В этом случае фактически всеКопируется, я бы сказал, что даже временный B может быть отброшен, но это отдельный вопрос.)
Тем не менее, оба времени жизни расширены до включающего блока if
.
// Both temporary A and temporary B's lifetime are extended to the end of the enclosing block,
// which is the if statement
if let Some(B(v @ 0...4)) = a(4).get_b() {
println!("some {}", v);
}
Должно ли это считаться несоответствием в Rust?Или я неправильно понимаю, и существует непротиворечивое правило, которое может объяснить это поведение?
Пример полного кода:
Обратите внимание, что вывод в Rust
some 4
Drop B 4
Drop A 4
, в то время как вывод в C ++
Drop A 4
some 4
Drop B 4
Я прочитал эту ветку Reddit и Rust Issue , что, на мой взгляд, весьма актуально, но я до сих пор не могу найти четкий набор правил жизни, который работает для всехслучаи в Rust.
Обновление:
Неясно, почему правило временного срока действия if
условного выражения не применяется к if let
.Я думаю, что let Some(B(v @ 0...4)) = a(4).get_b()
должно быть условным выражением, и, следовательно, время жизни временного A должно быть ограничено этим, а не всем оператором if
.
Поведение продления времени жизни временного B до всего *Ожидается выражение 1064 *, поскольку оно заимствовано при сопоставлении с образцом.