tg-me.com/rust_code/918
Last Update:
Какие строки и в каком порядке будут выведены на консоль при запуске этой программы? Приведите полный список выводимых сообщений.этого кода.
use std::mem;
struct Tracer(&'static str);
impl Drop for Tracer {
fn drop(&mut self) {
println!("Dropping {}", self.0);
}
}
struct Container {
tracer: Tracer,
}
fn make_tracer(name: &'static str) -> Tracer {
println!("Creating {}", name);
Tracer(name)
}
fn main() {
let a = make_tracer("a");
let b = make_tracer("b");
{
let temp = make_tracer("temp");
println!("Inside block");
// temp перемещается в c
let c = temp;
println!("Exiting block");
} // <- здесь c (то есть «temp») умирает
let mut container = Container {
tracer: make_tracer("container1"),
};
// замена поля: старый контейнер1 будет сброшен
container.tracer = make_tracer("container2");
println!("Before dropping b explicitly");
mem::drop(b);
println!("End of main");
} // <- здесь умирают: container.tracer ("container2"), затем a
```bash
Creating a
Creating b
Creating temp
Inside block
Exiting block
Dropping temp
Creating container1
Creating container2
Dropping container1
Before dropping b explicitly
Dropping b
End of main
Dropping container2
Dropping a```
Пояснение по шагам:
let a = make_tracer("a");
Сначала вызывается make_tracer("a"), который печатает
Creating a
и возвращает Tracer("a").
let b = make_tracer("b");
Аналогично:
Creating b
Блок { … }:
let temp = make_tracer("temp"); → Creating temp
println!("Inside block"); → Inside block
let c = temp; — просто перемещение, без нового вывода.
println!("Exiting block"); → Exiting block
В конце блока выходит из области видимости c (он же temp), срабатывает Drop → Dropping temp
Инициализация container:
rust
let mut container = Container {
tracer: make_tracer("container1"),
};
→ Creating container1
Перезапись поля tracer:
```rust
container.tracer = make_tracer("container2");
Сначала вычисляется правая часть → Creating container2.
Затем старый container.tracer (то есть container1) сбрасывается → Dropping container1.```
Явное удаление b:
```rust
println!("Before dropping b explicitly");
mem::drop(b);
→ Before dropping b explicitly
Затем drop(b) вызывает Drop для b → Dropping b```
Выход из main:
```rust
println!("End of main");
→ End of main```
После этого по правилам Rust объекты уничтожаются в порядке обратном созданию (LIFO):
Сначала поле container.tracer (уже “container2”) → Dropping container2
Затем переменная a → Dropping a
Таким образом и получается приведённая последовательность.