Когда хранилище используется для ресурса, который больше не принадлежит?
В строке 2 программы ниже выделен векторный ресурс. Когда программа заканчивается, векторный ресурс не принадлежит. Если ресурс вообще не принадлежит, когда он будет восстановлен? Есть ли объяснение с использованием терминологии семантики владения Rust и времени жизни, которое могло бы убедить программиста в том, что этот ресурс действительно исправлен?
fn main() {
let mut v = vec![1,2];
v = vec![3, 4];
}
1 ответ
когда [неизвестный ресурс] будет восстановлен?
С точки зрения Rust, элемент удаляется, когда он выходит из области видимости, что часто (но не всегда) соответствует концу блока. Когда он отбрасывается, любые ресурсы, которые являются частью предмета, также освобождаются.
Ресурсы могут означать память, как в примере с вектором, но могут также соответствовать другим вещам, таким как дескриптор файла или блокировка. Обычно это называется "Инициализация ресурсов - инициализация" (RAII).
убедить программиста, что этот ресурс действительно исправлен?
Вы никогда не сможете убедить кого-то, кто действительно не хочет верить ^_^. Тем не менее, вы можете реализовать Drop
Вы сами видите, когда предмет сбрасывается:
struct NoisyDrop(u8);
impl Drop for NoisyDrop {
fn drop(&mut self) {
println!("Number {} being dropped", self.0);
}
}
fn main() {
println!("step 1");
let mut nd = NoisyDrop(1);
println!("step 2");
nd = NoisyDrop(2);
println!("step 3");
}
Это будет иметь выход
step 1
step 2
Number 1 being dropped
step 3
Number 2 being dropped
Вы можете видеть, что первая переменная отбрасывается при замене ее привязки, так как больше нет возможности добраться до NoisyDrop(1)
значение. Вторая переменная удаляется, когда она выходит из области видимости из-за завершения метода.
семантика собственности и время жизни
Рассмотрим этот пример:
fn main() {
let mut v = vec![1];
v = vec![2];
}
Концептуально это можно записать как
fn main() {
{
let v = vec![1];
}
{
v = vec![2];
}
}
И этот пример
fn main() {
let v1 = vec![1];
let v2 = vec![2];
}
Может быть переписан как
fn main() {
{
let v1 = vec![1];
{
let v2 = vec![2];
}
}
}
Эти перезаписи показывают время жизни каждой переменной. Всякий раз, когда вы вызываете метод с универсальным параметром времени жизни, время жизни блока будет конкретным значением, которое подставляется вместо 'a
родовой.