I am new to Rust. Here is a piece of code for computer stock transaction. The Strategy will buy some stocks when the SignalTrigger triggers, and sell those stocks if after 30s/90s in different way. The code can't be compiled. Here is the code:
use std::cmp;
use std::cmp::Ordering;
use std::collections::BTreeMap;
use std::collections::BinaryHeap;
use std::convert::TryFrom;
use std::error::Error;
use std::fs::File;
use std::io;
use std::process;
#[derive(Debug)]
struct Depth {
ts: u32,
ap_vec: Vec<f64>,
bp_vec: Vec<f64>,
av_vec: Vec<u32>,
bv_vec: Vec<u32>,
}
struct Order {
ts: u32,
id: u32,
is_buy: bool,
is_mkt: bool,
vol: u32,
price: f64,
}
struct LongPosition {
vol_left: u32,
ts: u32,
}
struct Strategy {
order_id: u32,
prev_buy_ts: u32,
map_orderid_position: BTreeMap<u32, LongPosition>, // map<order_id, volume_left>
}
impl Strategy {
fn on_depth(&mut self, depth: &Depth) -> Vec<Order> {
let mut orders_vec: Vec<Order> = Vec::new();
for (order_id, long_position) in &mut self.map_orderid_position {
if depth.ts - long_position.ts > 90 * 1000 {
let order = self.make_order(depth.ts, false, true, long_position.vol_left, 0.0);
orders_vec.push(order);
} else if depth.ts - long_position.ts > 60 * 1000 {
let order = self.make_order(depth.ts,false,true,long_position.vol_left,depth.bp_vec[0]);
orders_vec.push(order);
}
}
return orders_vec;
}
fn make_order(&mut self, ts: u32, is_buy: bool, is_mkt: bool, vol: u32, price: f64) -> Order {
let order = Order {
id: self.order_id,
ts,
is_buy,
is_mkt,
vol,
price,
};
self.order_id = self.order_id + 1;
return order;
}
}
fn main() {
let empty_price_vec: Vec<f64> = Vec::new();
let map_orderid_position: BTreeMap<u32, LongPosition> = BTreeMap::new();
let mut strategy = Strategy {
prev_buy_ts: 0,
order_id: 0,
map_orderid_position: map_orderid_position,
};
}
The compile says:(I have comment line 88 and line 90 in the snippet)
error[E0499]: cannot borrow `*self` as mutable more than once at a time
--> src\main.rs:46:29
|
44 | for (order_id, long_position) in &mut self.map_orderid_position {
| ------------------------------
| |
| first mutable borrow occurs here
| first borrow later used here
45 | if depth.ts - long_position.ts > 90 * 1000 {
46 | let order = self.make_order(depth.ts, false, true, long_position.vol_left, 0.0);
| ^^^^ second mutable borrow occurs here
error[E0499]: cannot borrow `*self` as mutable more than once at a time
--> src\main.rs:49:29
|
44 | for (order_id, long_position) in &mut self.map_orderid_position {
| ------------------------------
| |
| first mutable borrow occurs here
| first borrow later used here
...
49 | let order = self.make_order(depth.ts,false,true,long_position.vol_left,depth.bp_vec[0]);
| ^^^^ second mutable borrow occurs here
error: aborting due to 2 previous errors; 12 warnings emitted
For more information about this error, try `rustc --explain E0499`.
error: could not compile `greeting`
I am a little confused about Rust, snippets like these are really common in other languages. Can you make an explanation and tell me how to fix(avoid) this situation?
You are borrowing the whole instance when you are calling self.make_order. The compiler cant be sure that you are not going the change map_orderid_position. Instead, you can create a standalone function and pass the mutable reference to order_id field to it.
impl Strategy {
fn on_depth(&mut self, depth: &Depth) -> Vec<Order> {
let mut orders_vec: Vec<Order> = Vec::new();
for (order_id, long_position) in &mut self.map_orderid_position {
if depth.ts - long_position.ts > 90 * 1000 {
let order = make_order(depth.ts, false, true, long_position.vol_left, 0.0, &mut self.order_id);
orders_vec.push(order);
} else if depth.ts - long_position.ts > 60 * 1000 {
let order = make_order(depth.ts,false,true,long_position.vol_left,depth.bp_vec[0], &mut self.order_id);
orders_vec.push(order);
}
}
return orders_vec;
}
}
fn make_order(ts: u32, is_buy: bool, is_mkt: bool, vol: u32, price: f64, order_id: &mut u32) -> Order {
let order = Order {
id: *order_id,
ts,
is_buy,
is_mkt,
vol,
price,
};
*order_id += 1;
return order;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With