Deref implementation in a barcode structure

I would like to implement Deref and DefrefMut in a structure that owns a barcode, for example:

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

Unable 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 you replace Box<Quack> with Box<String> (or a similar type), it will work. The problem is that Quack is a sign. But I'm not sure why this caused an error message. Any ideas?

My question is similar to another SO question , but not quite the same. In this question, the structure has a type parameter with a sign as a constraint. If in my question there is no type parameter.

I don't want to confuse the problems, but there is a good reason why I need Box<Quack> in my application. That is, I cannot replace Quack a type parameter. In case you don't care, the reason is discussed further in another SO question .

+5
source share
2 answers

If 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 } } 
+6
source

Based on Brian's answer and Shepmaster's explanation, I updated my code as follows. I also simplified the structure of QuackWrap . (This was not necessary, but it may be better than what I did 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 of destroying QuackWrap in deref and deref_mut . Some of those more obscure syntax rules elude me. But for now, this is normal.

+1
source

All Articles