Я пытался написать приложение, в котором пользователь может создавать объекты из шаблонов.
В моих снах код выглядит так:
struct DataTemplate {
tmp: u32,
}
struct Data<'a> {
name: &'a str,
tmp: u32,
}
struct Consumer<'a> {
items: Vec<Data<'a>>,
}
struct Library {
items: Vec<DataTemplate>,
}
struct Application<'a> {
library: Library,
consumer: Consumer<'a>,
}
impl DataTemplate {
fn new(data: u32) -> Self {
DataTemplate { tmp: data }
}
}
impl<'a> Data<'a> {
fn new(name: &'a str, tmp: u32) -> Self {
Data { name, tmp }
}
fn from_template(template: &DataTemplate, name: &'a str) -> Self {
Data::new(name, template.tmp)
}
}
impl<'a> Consumer<'a> {
fn new() -> Self {
Consumer { items: vec![] }
}
fn consume(&mut self, data: Data<'a>) {
self.items.push(data);
}
}
impl Library {
fn new() -> Self {
Library { items: vec![] }
}
fn add(&mut self, d: DataTemplate) {
self.items.push(d);
}
fn get(&self, index: usize) -> &DataTemplate {
&self.items[index]
}
}
impl<'a> Application<'a> {
fn new() -> Self {
Application {
library: Library::new(),
consumer: Consumer::new(),
}
}
fn get_library(&self) -> &Library {
&self.library
}
fn get_library_mut(&mut self) -> &mut Library {
&mut self.library
}
fn get_consumer_mut(&mut self) -> &mut Consumer<'a> {
&mut self.consumer
}
}
fn main() {
let mut app = Application::new();
use_it(&mut app);
}
fn use_it(app: &mut Application) {
app.get_library_mut().add(DataTemplate::new(1));
app.get_library_mut().add(DataTemplate::new(2));
app.get_library_mut().add(DataTemplate::new(3));
let item = app.get_library().get(1);
app.get_consumer_mut()
.consume(Data::from_template(item, "hi"));
}
Проблема в use_it
функция:
error[E0502]: cannot borrow `*app` as mutable because it is also borrowed as immutable
--> src/main.rs:89:5
|
88 | let item = app.get_library().get(1);
| --- immutable borrow occurs here
89 | app.get_consumer_mut()
| ^^^ mutable borrow occurs here
90 | .consume(Data::from_template(item, "hi"));
91 | }
| - immutable borrow ends here
Мне нужно получить неизменную ссылку на приложение (let item = app.get_library()
), чтобы получить шаблон, а затем после создания элемента данных из шаблона я должен добавить его к потребителюв приложении, теперь изменяемый, конечно (app.get_consumer_mut()
).
Есть ли какое-то общее решение для такой проблемы, или эта идея просто не в стиле Rust?