openlang

Отложить изменяемое заимствование блока очистки до его исполнения

Как написать в Rust устойчивую к панике конструкцию, похожую на Java try { ... } finally { ... }, чтобы блоки try и finally могли каждый изменяемо заимствовать одно значение?

Мне нужно, чтобы заимствования блока try заканчивались сразу при выходе из него, как обычном, так и при раскрутке стека из-за паники, а заимствования блока finally начинались лишь при переходе к нему.

С scopeguard::defer! замыкание приходится объявлять перед аналогом блока try, и изменяемое заимствование начинается сразу при создании этого замыкания, поэтому код, соответствующий блоку try, уже не может изменяемо заимствовать то же значение, которое держит замыкание.

Переведено с английскогоПоказать оригинал

Разговор продолжается 2

Следуя доводам
  1. Ссылка на ответ

    С scopeguard::defer! замыкание приходится объявлять перед аналогом блока try, и изменяемое заимствование начинается сразу при создании этого замыкания,

    Здесь defer!() не подходит, зато функция guard позволяет поместить значение внутрь scopeguard::ScopeGuard.

    поскольку ScopeGuard предоставляет Deref и DerefMut, к объекту-охраннику можно обращаться как к содержащемуся в нём значению.

    struct Resource {}
    
    // ownership of the resource goes into this destructor
    // a closure normally serves this purpose
    fn release_resource(resource: Resource) {
        println!("dropping resource");
    }
    
    fn main() {
        // obtain the resource, then give it a guard
        let resource: Resource = acquire_resource();
        let mut resource = guard(resource, release_resource);
        // borrowing the resource mutably is another option
        // let mut resource = guard(&mut resource, release_resource_by_mut);
    
        // access the enclosed resource through its guard
        resource.refresh();
        inspect_resource(&resource);
        change_resource(&mut resource);
    
        // leaving this scope runs the destructor
        // or disable the guard to recover the resource
        // without invoking its destructor
        // let resource = ScopeGuard::into_inner(resource);
    }
    Переведено с английскогоПоказать оригинал

Другие стороны того же вопроса

  1. Один и тот же вызов с sink, сначала копия, потом перенос

    Nim 2 решает, копировать или переносить, в каждой точке вызова. Не на уровне proc. Тот же аргумент, та же proc. Первый вызов…

    Ответы 2Последняя активность nim
  2. Ввод массивов символов через указатели

    Когда пытаюсь вводить с клавиатуры данные в массивы char, программа каждый раз падает. Как можно удобно считывать с клавиатур…

    Ответы 2Последняя активность c
  3. Может ли функция ввода обойтись без глобальных переменных?

    Хочу написать функцию, которая обрабатывает пользовательский ввод, фильтрует его и возвращает полученную строку вызвавшей её…

    Ответы 2Последняя активность c