How do I get my own adaptive methods to use an attribute object?

I have a trait that has “adapter methods” that use the method:

struct Bar<T>(T); trait Foo { fn make_bar(self) -> Bar<Self> where Self: Sized, { Bar(self) } } impl Foo for u8 {} impl Foo for bool {} 

This is modeled after Iterator . When I use Box<Iterator> , I can still call the adapter Iterator methods such as map or filter :

 fn main() { let a = vec![1, 2, 3]; let b: Box<Iterator<Item = u8>> = Box::new(a.into_iter()); let c = b.map(|x| x * 2); for z in c { println!("{}", z) } } 

However, the methods that I defined do not work the same:

 fn main() { let a: Box<Foo> = Box::new(42); a.make_bar(); } 

This fails with errors

 error[E0277]: the trait bound `Foo: std::marker::Sized` is not satisfied --> src/main.rs:18:7 | 18 | a.make_bar(); | ^^^^^^^^ `Foo` does not have a constant size known at compile-time | = help: the trait `std::marker::Sized` is not implemented for `Foo` 

It is absolutely correct that Foo has no size - that’s a trait. However, Box<Foo> should have a size, as I understand it. What does Iterator mean to do differently than my code?

+6
source share
1 answer

Because Iterator is an object, the Iterator object object implements Iterator .

Since impl<I: Iterator + ?Sized> Iterator for Box<I> object object implements Iterator .

Thus, in your case, the solution should implement Foo for Box<Foo> . This may be common as Iterator s ( impl<T: ?Sized + Foo> Foo for Box<T> { } ), or it may be specific ( impl Foo for Box<Foo> { } ).

+6
source

Source: https://habr.com/ru/post/988488/


All Articles