我正在尝试对现有实现进行一些测试,但我无法出于测试目的对其进行更改。
为了使测试正常进行,我需要将
dyn Thing
转换为 RealThing
。问题是我收到一个 Arc<Mutex<dyn Thing>>
并且必须调用 OtherTrait
上的方法,该方法是为 Arc<Mutex<RealThing>>
实现的。
还困惑吗?是的,我也是。
这里有一个简单的例子,用
Animal
, Mammal
, Horse
来更具体地说明:
// The goal here is to cast a dyn Animal into a Horse and
// call a method from Mammal, which is implemented by
// Arc<Mutex<Horse>. kinda crazy, yeah?
use std::any::Any;
use std::sync::{Arc, Mutex};
// I can't change this
pub trait Animal {
fn identify(&self) {
println!("I'm an animal");
}
fn as_any(&self) -> &dyn Any;
}
// I can't change this
pub trait Mammal {
fn identify_as_mammal(&self) -> String{
"I am a mammal".to_string()
}
}
// I can't change this
struct Horse<G> {
pub age: G,
}
// I can't change this
impl<G: 'static> Animal for Horse<G> {
fn as_any(&self) -> &dyn Any {
self
}
}
// I especially can't change this.
impl<G> Mammal for Arc<Mutex<Horse<G>>> {}
fn main() {
// I can't change this. I receive locked_dyn_animal.
let horse: Horse<usize> = Horse { age: 10 };
let locked_dyn_animal: Arc<Mutex<dyn Animal>> = Arc::new(Mutex::new(horse));
// ------ I can only change things below ------
// Attempt 1: This doesn't compile because it creates Arc<Mutex<&Horse<usize>>> instead of Arc<Mutex<Horse<usize>>>
let dyn_animal = locked_dyn_animal.lock().unwrap();
let horse_ref = <dyn Any>::downcast_ref::< Horse<usize> >(&dyn_animal).unwrap();
let locked_horse = Arc::new(Mutex::new(horse_ref));
// Attempt 2: This also doesn't compile for the same reason.
// let dyn_animal = locked_dyn_animal.lock().unwrap();
// let horse_ref = dyn_animal.as_any().downcast_ref::< Horse<usize> >().unwrap();
// let locked_horse = Arc::new(Mutex::new(horse_ref));
let lg = locked_horse.lock().unwrap();
println!("{}. My age is {}", lg.identify_as_mammal(), lg.age);
}
编译错误为:
error[E0599]: no method named `identify_as_mammal` found for struct `MutexGuard<'_, &Horse<usize>>` in the current scope
--> src/main.rs:60:38
|
60 | println!("{}. My age is {}", lg.identify_as_mammal(), lg.age);
| ^^^^^^^^^^^^^^^^^^ method not found in `MutexGuard<'_, &Horse<usize>>`
|
= help: items from traits can only be used if the trait is implemented and in scope
note: `Mammal` defines an item `identify_as_mammal`, perhaps you need to implement it
--> src/main.rs:19:1
|
19 | pub trait Mammal {
| ^^^^^^^^^^^^^^^^
注意:即使我添加了
impl<G> Mammal for Arc<Mutex<&Horse<G>>> {}
,我仍然得到相同的编译错误。
那么,有什么办法可以做到这一点,还是我只是运气不好?
除非您可以在
Mammal
上添加 Horse<G>
实现,否则如果不克隆 Arc<Mutex<_>>
中的具体值并创建您自己的 Arc<Mutex<_>>
包装它,就无法做到这一点。