Cross link. How?

Sorry for my Eng.
struct ABC<T,U,W>{

}
...
let var = [ABC[1,&othervar,&func];
let othervar = [ABC[2,&var,&func];

Can't find in book :frowning:
Tnx!

It's really unclear what is your question. You could try asking it in your native language, I'm sure someone would understand you.

var is & to othervar, but compiller not seen other var.

Структура.
Объявляем две переменных с типом структуры, но которые содерат ссылки на друг друга.
Пример, меню "Вернуться"
Переменные статичные (неизменяемые).
Пишем var до othervar, то первая не видит вторую, меняем их и ситуация повторяется.
Компилятор, похоже, однопроходный

Есть ли "легальные способы" выйти из ситуации.
На ассемблере, как два пальца, а тут (именно поэтому долгое время не учил языки всякие)
Большую часть времени думаешь, как с этим ... справиться (язык не имеет значения)

Посмотришь на код и думаешь: А фаланги он не сточил?

У тебя получается цикл из ссылок. Без unsafe такое реализовать нельзя.

Цикличные ссылки - это традиционное проблемное место для Rust, потому что компилятор хочет проверить их корректность статически, но у цикла нет чёткого отношения владения. Посмотри с такой стороны: в какой момент эта сладкая парочка должна быть уничтожена? Кто-то из них уйдёт первым, но тогда у второго ссылка окажется мёртвой.

Я рекомендую либо переосмыслить свой код и полностью избавиться от цикличности, либо использовать Rc или Arc. Для них как раз недавно был добавлен апи new_cyclic, который позволяет такое делать без заворачивания в Option.

Доброго ...
Спасиб за ответ.
Я думал над этим.
Это микро меню. Мой мозг отказывается усложнять )
На асме:
.mainmenu:
db "Первый!", &submenu,$0
...
.submenu:
db "Назад", &mainmenu, $0

Это не только Rust'a проблема )

З.Ы.: Может я упал в отрицание, но не могу понять, как упростить или улучшить. Тут проще некуда!

Ничего не понял. Объясни по-человечески постановку задачи.

Эмм...
7-ми сегментный индикатор.
На него выводим 4 символа (это всё пофиг) - название . Пункт меню.
Нажимаем вниз, меняется пункт.
При выборе выбираем из структуры &submenu (указатель на такую же структуру, содержащую подменю).
Т.е. структура (тип) одна! Название, ссылка, функция.
Если ссылка 0, то вызываем функцию.
В подменю тоже самое. Они одинаковые. Но! Подменю ссылается на переменную объявленную позже или наоборот главное, ссылается на переменную. что позже объявлена и компилятор ругается.
Получаются перекрёстные ссылки, т.е. одно ссылается на то, что не было ещё объявлено.
Может как-то завернуть нужно, но я в "хайливер" ни бум бум )

Блин, я 3 дня только читал и думал, как эту хрень завернуть )
Жесть, а там ещё, как Саркози символы представить!

Интересно, но не понимаю, как на этом можно аще что-то написать

struct Point<T,V,U> {
    name: T,
    sub: V,
    proc: U,
}
...
    let main_menu = [Point {name: "Men1",sub: &sub_menu, proc: &test},Point {name: "Men2",sub: &sub_menu, proc: &test}];
    let sub_menu = [Point {name: "Sub1",sub: &main_menu, proc: &test},Point {name: "Sub2", sub: &main_menu,proc: &test}];

FAIL

sub_menu -> main_menu
main_menu -> sub_menu

Очень тяжело понять тебя. Ты делаешь какую-то гуишку, и две менюшки могут менять содержимое друг друга? Может, вынести состояние в один общий объект, который будет доступен для чтения и изменения из двух мест?

Вообще гуи очень часто строят вокруг Rc<RefCell<MyType>> или Arc<RwLock<MyType>>. Почитай доки по Rc, RefCell, Arc, Mutex. Скорее всего из них можно нужное собрать.

Можно и по-другому делать, но сложнее объяснить.

Есть ссылка на репозиторий?

Если время не поджимает, то лучше начни с чего попроще. Какая-нибудь несложная консольная утилита - идеальный вариант. Например, преобразователь между форматами. Тут без крепкого знания теории и стандартной библиотеки далеко не уедешь, а ты похоже сразу вглубь ломанулся.

Не, я на асме пишу и мне все говорят, что я ... и нужно на языках высокого уровня!
Наткнулся на Rust. Вроде кошерный, а тут такое )

#![no_std] // from the previous step
#![no_main]
#![feature(llvm_asm)]

use panic_halt as _;
struct Point<T,V,U> {
    name: T,
    sub: V,
    proc: U,
}
#[no_mangle]
fn main() -> ! {
    let main_menu = [Point {name: "Men1",sub: &sub_menu, proc: &test},Point {name: "Men2",sub: &sub_menu, proc: &test}];
    let sub_menu = [Point {name: "Sub1",sub: &main_menu, proc: &test},Point {name: "Sub2", sub: &main_menu,proc: &test}];
    //let main_menu = [Point {name: "Men1",sub: &sub_menu, proc: &test},Point {name: "Men2",sub: &sub_menu, proc: &test}];
     loop{

     }
}

fn test() -> u8 {
    1+2
}

Вроде всё )
Куда проще то?

Rc<RefCell<MyType>> или Arc<RwLock<MyType>> .
#[no_std] :frowning:

Т.е. только массивы, ссылки. Минимум. Это Rust Embedded

#![feature(llvm_asm)], если что, уже не нужен. Ассемблер недавно стабилизировали. Docs

Этот код не делает ничего полезного, поэтому я не могу предложить, как сделать это по-другому. Тебе правда нужны ссылки в обе стороны?

Если бы у тебя была доступна стандартная библиотека, я бы сказал использовать Rc. Оборачиваешь главное меню и подменю в Rc, прямую ссылку делаешь как поле типа Rc. Обратную ссылку делаешь как Weak. Внутрь кладёшь RefCell, чтобы можно было изменять данные.

Но на #![no_std] таких простых решений нет. Тут надо внимательно разбираться, что и зачем ты делаешь, и скорее всего искать нужные крейты.

Например, можно взять какой-нибудь кастомный аллокатор, к которому прилагаются использующие его коллекции. Скажем, bumpalo. Или любой кастомный аллокатор, если использовать nightly фичи для поддержки аллокаторов в коллециях. Создаёшь аллокатор как локальную переменную фиксированного размера, дальше передаёшь всюду как аргумент.

Серьёзно, начни с чего-нибудь попроще. Гуи, no_std, embedded, циклы ссылок - слишком много на первый раз.

Ну, я думал, что мож на реальной железке будет интереснее и проще, а тут одни грабли )
А язык оч понравился. Легко читается. Си и Си++ аще с трудом понимаю -.-
Спсб, что потратили время :sneezing_face:

Другой вариант - самодельные указатели. Создаёшь большой массив, все объекты живут в этом массиве. Вместо ссылок используешь индексы в этом массиве. Тогда borrow checker проблем не создаст, но за тем, чтобы все ссылки были живыми, придётся вручную следить.

Вообще глянь Learning Rust with entirely too many linked lists, там проблемы с циклами подробно обсуждаются. Не знаю, есть ли на русском.

Спсб, английский не проблема при чтении, но писать ... не могу )

JFYI https://forum.rustycrate.ru + chats at rust-lang.ru

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.