简体   繁体   English

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

[英]Implementing Deref on a struct that owns a boxed trait

I'd like to implement Deref and DefrefMut on a struct that owns a boxed trait, eg: 我想在拥有盒装特征的结构上实现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
    }
}

This fails to compile with the following error: 无法编译时出现以下错误:

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     }

If I replace Box<Quack> with Box<String> (or a similar type), it works. 如果我用Box<String> (或类似的类型)替换Box<Quack> ,它可以工作。 The problem is that Quack is a trait. 问题是Quack是一个特质。 But I'm not sure why that generated the error message it did. 但我不确定为什么会产生错误消息。 Any ideas? 有任何想法吗?

My question is similar to another SO question , but not quite the same. 我的问题类似于另一个SO问题 ,但不完全一样。 In that question, the struct has a type parameter with the trait as a constraint. 在该问题中,struct具有类型参数,其中trait为约束。 Whereas in my question, there is no type parameter. 而在我的问题中,没有类型参数。

I don't want to confuse the issues, but there's a good reason that I need Box<Quack> in my application. 我不想混淆这些问题,但我有充分的理由在我的应用程序中需要Box<Quack> Ie I can't replace Quack with a type parameter. 即我不能用类型参数替换Quack In case you care, the reason is discussed further in another SO question . 如果您关心,原因将在另一个SO问题中进一步讨论

When in doubt, add more lifetime annotations: 如有疑问,请添加更多生命周期注释:

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
    }
}

Based on Brian's answer and Shepmaster's explanation, I updated my code as follow. 根据Brian的回答和Shepmaster的解释,我更新了我的代码如下。 I also simplified the QuackWrap struct. 我还简化了QuackWrap结构。 (That wasn't strictly necessary, but it's arguably better style than what I was doing before.) (这不是绝对必要的,但它的风格可能比以前更好。)

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
    }
}

There may be a more concise way to destructure QuackWrap in the deref and deref_mut implementations. 有可能是解构一个更简洁的方式QuackWrapderefderef_mut实现。 Some of those more obscure syntax rules elude me. 其中一些比较模糊的语法规则让我望而却步。 But for now this is fine. 但是现在这很好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM