应用程序架构:Mutable/Immutable 引用有问题
Application architecture: Problem with Mutable/Immutable reference
我尝试编写一个应用程序,用户可以在其中从模板创建对象。
在我的梦想中,代码如下所示:
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 的方式?
您需要确保在尝试访问使用者之前删除对库的引用。例如:
let data = Data::from_template(app.get_library().get(1), "hi");
app.get_consumer_mut().consume(data);
我尝试编写一个应用程序,用户可以在其中从模板创建对象。
在我的梦想中,代码如下所示:
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 的方式?
您需要确保在尝试访问使用者之前删除对库的引用。例如:
let data = Data::from_template(app.get_library().get(1), "hi");
app.get_consumer_mut().consume(data);