amarao: (Default)
[personal profile] amarao
Все эти возни на leetcode привели к тому, что я нашёл минималистичную конструкцию для обхода их странного Rc RefCell дерева.

pub fn postorder_traversal(root: Option<Rc<RefCell<TreeNode>>>) -> Vec<i32> {
fn dive(t: &Option<Rc<RefCell<TreeNode>>>, acc: &mut Vec<i32>){
if let Some(rc) = t{
let node = rc.borrow();
dive(&node.left, acc);
dive(&node.right, acc);
acc.push(node.val);
}
}
let mut acc = Vec::new();
dive(&root, &mut acc);
acc
}

Ключевое открытие тут: с любым Rc надо работать только через ref/mut ref. Как только появляется владение Rc, начинаются массовые проблемы, потому что rc.as_ref() создаёт короткоживущий референс и начинаются всякие выкрутасы. А c ref всё очень хорошо. Во-первых &option<T> автоматом конвертируется в & T после `if let Some...`. После того, как у нас появляется &T, простой .borrow() даёт нам правильную сущность с lifetime блока Some. Дальше мы можем обращаться к содержимому по точке, потому что там Deref реализован (насколько я понимаю, это именно Deref).

Вторая штука, которую я подглядел у соседей по решению: вложенные функции очень удобны, потому что находятся внутри Solution и их легко рекурсивно вызывать без Solution:: и т.д. Вложенные функции в Rust довольно банальны и всего лишь "записаны локально". В отличие от питона у них нет никаких признаков захвата замыкания (в питоне вложенные функции - метод создания замыканий), т.е. это исключительно кнопкодавное удобство.

Date: 2023-01-01 12:54 pm (UTC)
juan_gandhi: (Default)
From: [personal profile] juan_gandhi

Вот этот код выглядит вполне замечательно.

Profile

amarao: (Default)
amarao

September 2025

S M T W T F S
 12345 6
78 910111213
14151617181920
21222324252627
282930    

Most Popular Tags

Page Summary

Style Credit

Expand Cut Tags

No cut tags
Page generated Sep. 17th, 2025 11:50 am
Powered by Dreamwidth Studios