Hello people,
I recently met a use case, where I will have to pass some handlers into a register function.
The handler api is defined as a trait implemented on a struct, so I can just pass-in the dedicated object.
I have created a dummy code to better illustrate this issue:
pub trait DisplayHandler {
fn display_something(&self);
}
pub trait ErrorHandler {
fn display_error(&self, error: &str);
}
fn register_test_trait<
D: DisplayHandler + Send + 'static,
E: ErrorHandler + Send + 'static,
> (
display_handler: F,
error_handler: E,
) {
let _ = std::thread::spawn(move|| {
loop {
display_handler.display_something();
std::thread::sleep(std::time::Duration::from_secs(2));
}
});
let _ = std::thread::spawn(move|| {
loop {
error_handler.display_error("I am an error");
std::thread::sleep(std::time::Duration::from_secs(5));
}
});
}
pub struct MyStruct {}
impl DisplayHandler for MyStruct {
fn display_something(&self) {
println!("Display handler: showing something");
}
}
impl ErrorHandler for MyStruct {
fn display_error(&self, error: &str) {
println!("Error handler: {}", error);
}
}
fn main() {
let my_struct = MyStruct {};
let my_struct = std::sync::Arc::new(my_struct);
let my_struct_display = my_struct.clone();
let my_struct_error = my_struct.clone();
register_test_trait(my_struct_display, my_struct_error );
loop {
std::thread::sleep(std::time::Duration::from_millis(200));
}
}
As you can see the two handler traits, DisplayHandler
and ErrorHandler
. This is the required API passing to register_test_trait
function, where the two handlers could be used in the same thread or different.
What I did on my side is that I am trying to implement these two traits onto one struct, MuStruct
. Then before I try to pass to the register function.
I try to wrap my_struct
with Arc pointer and created two duplicated copy, and pass the copied struct in.
However, the compiler doesn't seem happy with this, it says:
error[E0277]: the trait bound `std::sync::Arc<MyStruct>: DisplayHandler` is not satisfied
--> src/main.rs:52:5
|
9 | fn register_test_trait<
| -------------------
10 | D: DisplayHandler + Send + 'static,
| -------------- required by this bound in `register_test_trait`
...
52 | register_test_trait(my_struct_display, my_struct_error );
| ^^^^^^^^^^^^^^^^^^^ the trait `DisplayHandler` is not implemented for `std::sync::Arc<MyStruct>`
error[E0277]: the trait bound `std::sync::Arc<MyStruct>: ErrorHandler` is not satisfied
--> src/main.rs:52:5
|
9 | fn register_test_trait<
| -------------------
10 | D: DisplayHandler + Send + 'static,
11 | E: ErrorHandler + Send + 'static,
| ------------ required by this bound in `register_test_trait`
...
52 | register_test_trait(my_struct_display, my_struct_error );
| ^^^^^^^^^^^^^^^^^^^ the trait `ErrorHandler` is not implemented for `std::sync::Arc<MyStruct>`
Regarding to the official document: ** Arc<T>
automatically dereferences to T
(via the Deref
trait), so you can call T
's methods on a value of type Arc<T>
**, I shouldn't encounter this error?
Can anyone help me figure out what's going wrong?