I'm used to writing code in python and C++ and try to get along with rust. I want to pass an object to a thread and call a method of this object.
In addition, the object is passed to the thread by dependency injection because I aim to reuse this module.
When the function expects the Object FIFO, everything's fine. But when using the trait, it fails.
I get the following error when passing the clone of the object to the thread:
borrowed data escapes outside of function requirement occurs because of the type
Mutex<&dyn testTrait>, which makes the generic argument&dyn testTraitinvariant the structMutex<T>is invariant over the parameterT
use std::thread;
use std::sync::{Arc, Mutex};
pub trait testTrait: Send + Sync {
fn test(&self, i: i32) -> i32;
}
pub struct FIFO {}
unsafe impl Send for FIFO {}
unsafe impl Sync for FIFO {}
impl testTrait for FIFO {
fn test(&self, i: i32) -> i32 {
return i;
}
}
impl FIFO {}
fn main() {
let fifo = FIFO {};
caller(&fifo);
}
pub fn caller(t: &dyn testTrait) {
let a = Arc::new(Mutex::new(t));
let clone = a.clone();
thread::spawn(move || {
if let Ok(mut x) = clone.lock() {
x.test(5);
}
});
}
Box<dyn testTrait>parameter or usestd::thread::scopeunsafe impl Send for FIFOis a bad sign. That should not be necessary. Those are derived automatically if yourstructis fine. If it isn't, don't just make Rust assume it is. Don't bust outunsafeto solve problems. You can probably go your whole career without needing to do that if you do things the Rust way.Arc<Mutex<Box<dyn X>>if you want read-write access, or justBox<dyn X>if it's strictly read-only.Arc.unsafe impls are also completely unecessary (the code wotks without them).