Hi,
I wrote this code:
use std::thread;
use std::sync::{Arc, Mutex, Condvar};
use rand::Rng;
struct Account {
user_name:String,
money:Arc<(Mutex<f32>, Condvar)>
}
impl Account {
fn change_money(&self, amount:f32) {
let (money_lock, cond) = &*self.money;
cond.wait_while(money_lock.lock().unwrap(), |m| {*m + amount < 0.0});
let mut money = money_lock.lock().unwrap();
*money += amount;
cond.notify_all();
}
fn get_user_name(&self) -> String {
self.user_name.clone()
}
fn get_money(&self) -> f32 {
let (lock, _) = &*self.money;
let money = lock.lock().unwrap();
*money
}
fn new() -> Account {
Account {
user_name: "unknow".to_string(),
money: Arc::new((Mutex::new(0.0f32), Condvar::new()))
}
}
}
struct Bank {
accounts:Vec<Account>
}
impl Bank {
fn create_account(&mut self, name: String, m: f32) {
self.accounts.push(Account{
user_name: name,
money: Arc::new((Mutex::new(m), Condvar::new()))
});
}
fn transfer_money(&self, name_a: &String, name_b: &String, amount: f32) -> bool {
let wrap_acc_a = self.get_account_by_name(name_a);
let wrap_acc_b = self.get_account_by_name(name_b);
if let Some(acc_a) = wrap_acc_a {
if let Some(acc_b) = wrap_acc_b {
acc_a.change_money(-amount);
acc_b.change_money(amount);
} else {
return false;
}
} else {
return false;
}
true
}
fn total_money(&self) -> f32 {
let mut sum:f32 = 0.0;
for acc in self.accounts.iter() {
sum += acc.get_money();
}
sum
}
fn random_transfer(&self, name_a: String, name_b: String) -> thread::JoinHandle<_> {
thread::spawn(move || {
let acc_a = self.get_account_by_name(&name_a);
let acc_b = self.get_account_by_name(&name_b);
let mut rng = rand::thread_rng();
loop {
let rand_money:f32 = rng.gen_range(0.0..100.0);
self.transfer_money(&name_a, &name_b, rand_money);
println!("Try to transfer {0}
From {1}({2}) to {3}({4}), Bank Total Money {5}", rand_money, name_a, acc_a.unwrap().get_money(),
name_b, acc_b.unwrap().get_money(), self.total_money());
}
})
}
fn get_account_by_name (&self, name:&String) -> Option<&Account> {
self.accounts.iter().position(|x|x.get_user_name() == *name).map(|i| &self.accounts[i])
}
fn new() -> Bank {
Bank {
accounts: Vec::new()
}
}
}
fn main() {
let mut bank = Bank::new();
bank.create_account("Hahaha".to_string(), 100.0f32);
bank.create_account("HeiHei".to_string(), 100.0f32);
}
but the compiler report
error[E0391]: cycle detected when computing function signature of `<impl at src/main.rs:41:1: 101:2>::random_transfer`
--> src/main.rs:75:5
|
75 | fn random_transfer(&self, name_a: String, name_b: String) -> thread::JoinHandle<_> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: ...which requires type-checking `<impl at src/main.rs:41:1: 101:2>::random_transfer`...
--> src/main.rs:75:5
|
75 | fn random_transfer(&self, name_a: String, name_b: String) -> thread::JoinHandle<_> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: ...which again requires computing function signature of `<impl at src/main.rs:41:1: 101:2>::random_transfer`, completing the cycle
note: cycle used when collecting item types in top-level module
how can I solve this?