扩展特征上的可变借用

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

我有一个实现扩展特征的动态调度引用向量。我还希望能够将它们传递给接受基本特征的函数:

use std::borrow::BorrowMut;

trait MyTrait {
    fn doit(&mut self);
}

trait MyOtherTrait: MyTrait {
    fn doit_too(&mut self);
}

fn doit<T>(items: &mut [T])
where T: BorrowMut<dyn MyTrait>
{
    for item in items.iter_mut() {
        item.borrow_mut().doit();
    }
}

struct A {}

impl MyTrait for A {
    fn doit(&mut self) { println!("AAAAA!"); }
}

impl MyOtherTrait for A {
    fn doit_too(&mut self) { println!("22222!"); }
}

fn main() {
    let mut boxes: Vec<Box<dyn MyOtherTrait>> = vec![A{}, A{}, A{}].into_iter().map(|a| Box::new(a) as Box<dyn MyOtherTrait>).collect();
    doit(&mut boxes);
    for item in boxes.iter_mut() {
        item.doit_too();
    }
}
error[E0277]: the trait bound `Box<dyn MyOtherTrait>: BorrowMut<(dyn MyTrait + 'static)>` is not satisfied
  --> src/main-dyn.rs:31:10
   |
31 |     doit(&mut boxes);
   |     ---- ^^^^^^^^^^ the trait `BorrowMut<(dyn MyTrait + 'static)>` is not implemented for `Box<dyn MyOtherTrait>`
   |     |
   |     required by a bound introduced by this call
   |
   = help: the trait `BorrowMut<dyn MyOtherTrait>` is implemented for `Box<dyn MyOtherTrait>`
note: required by a bound in `doit`
  --> src/main-dyn.rs:12:10
   |
11 | fn doit<T>(items: &mut [T])
   |    ---- required by a bound in this function
12 | where T: BorrowMut<dyn MyTrait>
   |          ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `doit`

For more information about this error, try `rustc --explain E0277`.
error: could not compile `scratchpad` (bin "dyn") due to previous error

终身要求

'static
从何而来?如何将
MyOtherTrait
框的向量处理为
MyTrait

作为参考,我尝试从

Vec<&mut dyn MyTrait>
创建第二个向量
boxes
,但是当我调用该函数时,这会导致多个可变借用。

rust traits dynamic-dispatch
1个回答
0
投票

您可以将

doit
中的要求放宽为:

fn doit<T, U>(items: &mut [T])
where
    T: AsMut<U>,
    U: MyTrait + ?Sized,
{
    for item in items.iter_mut() {
        item.as_mut().doit();
    }
}

不需要它直接给你

dyn MyTrait
,只要任何可以产生对实现特征的可变引用的东西,你就可以将特征对象传递给也实现超级特征的东西。

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