#rust
#Ржавчина
Вопрос:
например. нужен глобальный объект и определить объект во время выполнения
class A{
};
A* a = nullptr;
// B inherit from A
void Import(B* b){
a = b;
}
Я пытался использовать Dyn, но должен определить тип
static mut instance: amp;dyn plugin::BasePlugin;
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^help: provide a definition for the static: `= <expr>;`
Комментарии:
1. В целом это антипаттерн. Я бы предпочел иметь локальный объект
let mut instance: Box<dyn plugin::BasePlugin>
, который будет служить «контекстом», который я передаю в качестве аргумента своим функциям2. Сообщение об ошибке сообщает вам, что статическую переменную нельзя отменить, поэтому вам нужно присвоить ей начальное значение. Поскольку ссылка не может быть нулевой, самое близкое, что вы можете сделать, это использовать
Option
with:static mut instance: Option<amp;dyn plugin::BasePlugin> = None;
хотя, как сказал @AlexeyLarionov, глобальные изменяемые переменные являются плохим шаблоном (на любом языке), поэтому Rust делает их очень сложными в использовании.
Ответ №1:
Вы не должны использовать static mut
. Это небезопасная конструкция, предназначенная для низкоуровневого кода, а не для обычных пользователей, которым просто нужна глобальная переменная.
Rust предполагает, что однопоточных программ не существует, поэтому каждая глобальная переменная должна быть потокобезопасной. Поэтому, чтобы изменить его, вам придется использовать a Mutex
или какую-либо другую потокобезопасную альтернативу, например ArcSwap
. Вам нужно lazy_static
будет инициализировать эти типы.
Вы не сможете использовать только какую-либо временную ссылку, ограниченную областью действия, в глобальной переменной. amp;
это не универсальный способ ссылки на объекты в Rust. Рассмотрите возможность использования Box<dyn BasePlugin>
или Arc<dyn BasePlugin>
вместо этого. Они позволяют хранить объекты по ссылке без ограничений по сроку службы.
Вы могли бы использовать amp;'static
ссылку, но на практике это потребовало бы утечки памяти кучи. Если вы планируете установить переменную один раз, все будет в порядке. Если вы планируете установить его более одного раза, это не элегантно и может стать проблемой.
И, наконец, подумайте о том, чтобы вообще не использовать глобальные переменные. Создайте объекты, которые вам нужны, хранящиеся в локальных переменных (даже в начале main()
), и передайте их в качестве аргументов функциям, которые в них нуждаются. Вы могли бы создать struct App
и поместить нужные вам данные в качестве полей этой структуры.