如何向下转换为 MyStruct 并访问 Arc<Mutex<MyStruct>> 实现的方法?

问题描述 投票:0回答:1

我正在尝试对现有实现进行一些测试,但我无法出于测试目的对其进行更改。

为了使测试正常进行,我需要将

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>>> {}
,我仍然得到相同的编译错误。

那么,有什么办法可以做到这一点,还是我只是运气不好?

rust traits
1个回答
0
投票

除非您可以在

Mammal
上添加
Horse<G>
实现,否则如果不克隆
Arc<Mutex<_>>
中的具体值并创建您自己的
Arc<Mutex<_>>
包装它,就无法做到这一点。

© www.soinside.com 2019 - 2024. All rights reserved.