Денис
если не нужна многопоточность, то юзай Rc
Денис
если нужна — Arc
Rostyslav
Возможно, многие проблемы можно было бы решить быстрее и лучше, с помощью них.
Rostyslav
понял.
Денис
а ты без них не решишь никак
Денис
pub fn nodes_mut(&mut self) -> Vec<&mut TreeNode<T>> {
let mut all_nodes = vec![];
for node in self.get_mut_children().iter_mut() {
let node: &mut TreeNode<T> = node;
let is_empty = node.get_children().is_empty();
all_nodes.push(node);
if !is_empty {
let mut inner_nodes = all_nodes.pop().unwrap().nodes_mut();
all_nodes.append(&mut inner_nodes);
}
}
all_nodes.insert(0, self);
all_nodes
}
Денис
вот тебе пример, где компилятор выдаёт доходчивую ошибку
Денис
а именно
Денис
42 | for node in self.get_mut_children().iter_mut() {
| ---- first mutable borrow occurs here
...
51 | all_nodes.insert(0, self);
| ^^^^ second mutable borrow occurs here
Денис
с пушем, разумеется, та же история
Rostyslav
У меня просто этот проект, это прям спектр моей работы с раст:)
Сначала я ломал бороу чекер через unsafe, потом всё в сплошную заколотил клонами, а теперь вот опять, наверное, костыли горожу:)
Денис
> я ломал бороу чекер через unsafe
вот это ваще последнее дело
Денис
юзай счётчик ссылок и будет тебе счастье)
Антон
Антон
Простите, не удержался
Денис
=)
Rostyslav
Вот, как я это удалял:))
https://github.com/AtomicInteger/one_more_dstruct/commit/65ef44f2ddc4184b5d1855adb1c56d727ba341fe
Денис
суров
պլհկ
там двойной мутабл бороу, как от этого рц поможет?
Денис
Денис
Kirill
Тут кто-то писать на расте на андроиде хотел...
Kirill
как сделать так же?
Kirill
ну не
Денис
@AtomicInteger по сути дела, ты хочешь скопировать мутабельные ссылки
Denys
поидее ему нужен рц + рефселл
պլհկ
по идее ему нужно не элементы пушить туда-сюда, а индексы :)
Denys
ну да, но при том чт оесть сейчас по другому как то неизвестно как сделать
Денис
да ваще жесть конечно
պլհկ
да тут даже с рефцелами сомнительно (может и можно извернуться)
Денис
я бы сделал какой-нибудь метод типа traverse_mut, который бы принимал closure
Rostyslav
Денис
ога
Денис
ща попробую запилить
Rostyslav
Ну, такое я буду делать, это в планах
Rostyslav
А может действительно сразу сделать..
Denys
заимплементить итератор как dfs?)
Kirill
о да, cargo на моём ведре
Денис
@AtomicInteger это кстати нормально, что у тебя фукнция только один уровень вложенности делает?
Rostyslav
Денис
ну точнее два: корневая нода, её дети, и дети детей
Денис
да
Rostyslav
Не нормально, но я вроде проверял, что все проходит
Денис
каким таким волшебным образом?
Денис
аа, nodes_mut() же делается
Денис
всё, вижу
Денис
я дурак)
Rostyslav
Рекурсивно, да.
Денис
pub fn traverse_mut<F>(&mut self, mut f: F)
where
F: FnMut(&mut TreeNode<T>),
{
f(self);
for node in self.get_mut_children().iter_mut() {
node.traverse_mut(&mut f);
}
}
Rostyslav
Денис
даже вот
Денис
pub fn traverse_mut<F>(&mut self, mut f: F)
where
F: FnMut(&mut TreeNode<T>),
{
f(self);
self.get_mut_children()
.iter_mut()
.for_each(|node| node.traverse_mut(&mut f));
}
Denys
Денис
правда тут рекурсия и стэк растёт
Rostyslav
Денис
имхо лучше сразу так и делай
Денис
от get_mut_parent_by_val конечно придётся отказаться сразу)
Денис
да, поэтому чтобы полноценно что-то можно было делать, надо имлементить итератор
Денис
это скорее пруф оф концепт
Rostyslav
Ну, такое понадобится для дерева, но я пока хотя бы минимальный CRUD пытаюсь запилить
Денис
ну вот nodes_mut сделать точно не получится. смотри, у тебя после того, как функция отработала, остаётся оригинальный node, и вектор, в которм хранятся мутабельные ссылки на всех его детей и на него самого
Денис
ну кагбе всё
Денис
(а в оригинальном node хранятся ссылки на детей)
Rostyslav
Ну это да, понимаю. Ну хз, гляну ещё завтра на указатели, мб получится чего
Денис
в тех же плюсах так легко можно сделать, но, по сути, ты предоставляешь пользователю апи, с помощью которого можно лёгким движением пальца сломать вообще всё
Денис
указатели — это ансейф
Denys
ну если закостылить хранение в рц рефселл то мб и прокатит)
Denys
но апи тако говно будет)
Денис
ну мб и прокатит, то апи будет просто неюзабельным
Денис
Denys
прсто мб тебе не нужен иенно такой метод (который все возвращает)?
Denys
и лучше это как то выделить в отдельные методы
Денис
да и оно банально не будет работать, потому что RefCell::borrow_mut всегда пустой будет
Денис