首页 文章

在拥有盒装特征的结构上实现Deref

提问于
浏览
5

我想在拥有盒装特征的结构上实现 DerefDefrefMut ,例如:

use std::ops::{Deref, DerefMut};

trait Quack {
    fn quack(&self);
}

struct QuackWrap {
    value: Box<Quack>
}

impl Deref for QuackWrap {
    type Target = Box<Quack>;

    fn deref<'a>(&'a self) -> &'a Box<Quack> {
        &self.value
    }
}

impl DerefMut for QuackWrap {
    fn deref_mut<'a>(&'a mut self) -> &'a mut Box<Quack> {
        &mut self.value
    }
}

无法编译时出现以下错误:

src/main.rs:14:5: 16:6 error: method `deref` has an incompatible type for trait: expected bound lifetime parameter 'a, found concrete lifetime [E0053]
src/main.rs:14     fn deref<'a>(&'a self) -> &'a Box<Quack> {
src/main.rs:15         &self.value
src/main.rs:16     }
src/main.rs:20:5: 22:6 error: method `deref_mut` has an incompatible type for trait: expected bound lifetime parameter 'a, found concrete lifetime [E0053]
src/main.rs:20     fn deref_mut<'a>(&'a mut self) -> &'a mut Box<Quack> {
src/main.rs:21         &mut self.value
src/main.rs:22     }

如果我用 Box<String> (或类似的类型)替换 Box<Quack> ,它可以工作 . 问题是 Quack 是一个特征 . 但我不确定为什么会产生错误消息 . 有任何想法吗?

我的问题类似于another SO question,但不完全一样 . 在该问题中,struct具有一个类型参数,其特征为trait . 而在我的问题中,没有类型参数 .

我没有't want to confuse the issues, but there'这是我在申请中需要 Box<Quack> 的一个很好的理由 . 即我无法用类型参数替换 Quack . 如果你在意,原因是discussed further in another SO question .

2 回答

  • 6

    如有疑问,请添加更多生命周期注释:

    use std::ops::{Deref, DerefMut};
    
    trait Quack {
        fn quack(&self);
    }
    
    struct QuackWrap<'b> {
        value: Box<Quack + 'b>
    }
    
    impl<'b> Deref for QuackWrap<'b>{
        type Target = Box<Quack + 'b>;
    
        fn deref<'a>(&'a self) -> &'a Box<Quack + 'b> {
            &self.value
        }
    }
    
    impl<'b> DerefMut for QuackWrap<'b> {
        fn deref_mut<'a>(&'a mut self) -> &'a mut Box<Quack + 'b> {
            &mut self.value
        }
    }
    
  • 1

    根据Brian _1274646的解释,我更新了我的代码如下 . 我还简化了 QuackWrap 结构 . (那可能是比以前更好的风格 . )

    use std::ops::{Deref, DerefMut};
    
    trait Quack {
        fn quack(&self);
    }
    
    struct QuackWrap(Box<Quack>);
    
    impl Deref for QuackWrap {
        type Target = Box<Quack + 'static>;
    
        fn deref<'a>(&'a self) -> &'a Box<Quack + 'static> {
            let QuackWrap(ref v) = *self;
            v
        }
    }
    
    impl DerefMut for QuackWrap {
        fn deref_mut<'a>(&'a mut self) -> &'a mut Box<Quack + 'static> {
            let QuackWrap(ref mut v) = *self;
            v
        }
    }
    

    可能有一种更简洁的方法来解析 derefderef_mut 实现中的 QuackWrap . 其中一些比较模糊的语法规则让我望而却步 . 但是现在这很好 .

相关问题