问题
Background:
I'm writing a RDBMS in rust
The db.catalog maintain a hashmap from table_id to table:
pub struct Catalog {
table_id_table_map: HashMap<i32, Box<dyn Table>>,
}
And when I add a boxed table to the catalog, move occurred. Then I can't use table instance anymore:
// create table
let table = create_random_heap_table(....);
// add to catalog
db.get_catalog().add_table(Box::new(table), "heap table", "");
// access table instance
let table_id = table.get_id();
compile error:
error[E0382]: borrow of moved value: `table`
--> src/lib.rs:113:32
|
103 | let table = create_random_heap_table(
| ----- move occurs because `table` has type `table::HeapTable`, which does not implement the `Copy` trait
...
111 | db.get_catalog().add_table(Box::new(table), "heap table", "");
| ----- value moved here
112 |
113 | let table_id = table.get_id();
| ^^^^^ value borrowed here after move
回答1:
Once your Catalog
takes ownership of the table, you can access it via reference.
If the use case you are describing is common, maybe you can adapt your add_table
method to return a reference to the table which has just been added.
HashMap
provides the Entry API as an ergonomic way to do this - for instance your add_table
might look something like this:
fn add_table(&mut self, table: Box<dyn Table>/*, ... other arguments */) -> &mut Box<dyn Table> {
let id = // figure out id somehow
// Insert table into catalog and return a reference to it
self.table_id_table_map.entry(id).or_insert(table)
}
In that simplified example I am not considering what happens if the map already has an entry with the given id
- there are similar patterns you can use to check for that if you logic requires it.
Now you can use it like this:
// create table
let table = create_random_heap_table(....);
// add to catalog
let table = db.get_catalog().add_table(Box::new(table), "heap table", "");
// access table instance
let table_id = table.get_id();
来源:https://stackoverflow.com/questions/62273711/rust-pass-box-reference-without-move