Generics 如何在铁锈中实施装饰?

Generics 如何在铁锈中实施装饰?,generics,rust,iterator,lifetime,borrow-checker,Generics,Rust,Iterator,Lifetime,Borrow Checker,我正在学习生锈,我被一个玩具的例子困住了。我已经阅读了关于生命周期的文档,还有一些关于堆栈溢出的问题。我已经花了一个多星期的时间,但我仍然被困住了,所以我决定向社区寻求帮助 我有一个generic traitBookSide,它返回booksiterator(它扩展了通常的Iterator)。我有两个BookSide和booksiterator的实现:ArrayBookSide和CommissionBookSide 第一个是有状态的。发动机罩下有一个Vec 第二个是无状态的:它包装了一些其他的B

我正在学习生锈,我被一个玩具的例子困住了。我已经阅读了关于生命周期的文档,还有一些关于堆栈溢出的问题。我已经花了一个多星期的时间,但我仍然被困住了,所以我决定向社区寻求帮助

我有一个generic trait
BookSide
,它返回
booksiterator
(它扩展了通常的
Iterator
)。我有两个
BookSide
booksiterator
的实现:
ArrayBookSide
CommissionBookSide

  • 第一个是有状态的。发动机罩下有一个
    Vec
  • 第二个是无状态的:它包装了一些其他的
    BookSide
  • 我的目标仅仅是编译整个内容。我在解决问题,并遵循编译器的建议。此过程产生以下代码

    use std::marker::PhantomData;
    
    fn main() {
        println!("Hello, world!");
    }
    
    // traits
    
    pub trait BookIterator<'a>: Iterator<Item=f64> {}
    
    pub trait BookSide<'a> {
        type BookIteratorType: BookIterator<'a>;
    
        fn book_iterator(&self) -> Self::BookIteratorType;
    }
    
    // implementation 1: stateful
    
    pub struct ArrayBookSide {
        quotes: Vec<f64>,
    }
    
    pub struct ArrayBookSideIterator<'a> {
        quotes_iter: std::slice::Iter<'a, f64>,
    }
    
    impl<'a> BookSide<'a> for ArrayBookSide {
        type BookIteratorType = ArrayBookSideIterator<'a>;
    
        fn book_iterator(&self) -> Self::BookIteratorType {
            ArrayBookSideIterator { quotes_iter: self.quotes.iter() }
        }
    }
    
    impl<'a> Iterator for ArrayBookSideIterator<'a> {
        type Item = f64;
    
        fn next(&mut self) -> Option<Self::Item> {
            self.quotes_iter.next().map(|&quote| quote)
        }
    }
    
    impl<'a> BookIterator<'a> for ArrayBookSideIterator<'a> {}
    
    // implementation 2: delegating
    
    pub struct CommissionBookSide<'a, B>
        where B: BookSide<'a> {
        base_book_side: B,
        multiplier: f64,
        _marker: PhantomData<&'a B>,
    }
    
    impl<'a, B> CommissionBookSide<'a, B>
        where B: BookSide<'a> {
        pub fn new(base_book_side: B) -> CommissionBookSide<'a, B> {
            CommissionBookSide { base_book_side, multiplier: 1.1, _marker: PhantomData {} }
        }
    }
    
    impl<'a, B> BookSide<'a> for CommissionBookSide<'a, B>
        where B: BookSide<'a> {
        type BookIteratorType = CommissionIterator<'a, B::BookIteratorType>;
    
        fn book_iterator(&self) -> Self::BookIteratorType {
            CommissionIterator {
                base_iterator: self.base_book_side.book_iterator(),
                multiplier: self.multiplier,
                _marker: PhantomData {},
            }
        }
    }
    
    pub struct CommissionIterator<'a, BI>
        where BI: BookIterator<'a> {
        base_iterator: BI,
        multiplier: f64,
        _marker: PhantomData<&'a BI>,
    }
    
    impl<'a, BI> Iterator for CommissionIterator<'a, BI>
        where BI: BookIterator<'a> {
        type Item = BI::Item;
    
        fn next(&mut self) -> Option<Self::Item> {
            self.base_iterator.next().map(|quote| quote * self.multiplier)
        }
    }
    
    impl<'a, BI> BookIterator<'a> for CommissionIterator<'a, BI>
        where BI: BookIterator<'a> {}
    
    使用std::marker::PhantomData;
    fn main(){
    println!(“你好,世界!”);
    }
    //特征
    图书迭代器{
    类型BookIterator类型:BookIterator{
    国际热核实验堆:标准::切片::国际热核实验堆书架;
    fn book_迭代器(&self)->self::BookIteratorType{
    ArrayBookSideIterator{quotes\u iter:self.quotes.iter()}
    }
    }
    恳求{
    类型项=f64;
    fn下一步(&mut self)->选项{
    self.quotes_iter.next().map(|"e | quote)
    }
    }
    ArrayBookSideIterator的impl
    B:书边,
    }
    恳求
    哪里B:书边{
    CommissionBookSide{base{book}side,乘数:1.1,{marker:PhantomData{}
    }
    }
    委托书{
    类型BookIteratorType=CommissionIterator
    其中BI:BookIterator,
    }
    恳求
    其中BI:BookIterator BookIterator
    其中BI:BookIterator src/main.rs:27:6
    |
    27 |适用于ArrayBookSide的impl{
    |      ^^
    注意:…以便类型兼容
    -->src/main.rs:30:55
    |
    30 | fn book_迭代器(&self)->self::BookIteratorType{
    |  _______________________________________________________^
    31 | | ArrayBookSideIterator{quotes_iter:self.quotes.iter()}
    32 | |     }
    | |_____^
    =注意:预期为`书边`
    

    我可能不应该使用
    幻影数据
    ?对我来说,它看起来过于复杂,是一种解决方法。我已经发布了。

    你的问题基本上归结为以下几点。这里的问题是什么

    fn图书迭代器{
    //^^^^^^需要是“&”a[f64]`
    slice.iter()
    }
    
    方法
    book\u迭代器(&self)
    返回一个
    book迭代器:迭代器{}
    酒吧和书边;
    //'此处在特征方法签名中添加了一个
    fn book_迭代器(&'a self)->self::BookIteratorType;
    }
    //实现1:有状态
    发布结构ArrayBookSide{
    引用:Vec,
    }
    发布结构ArrayBookSideIterator,
    }
    ArrayBookSide的impl{
    类型BookIterator type=ArrayBookSideIterator迭代器的ArrayBookSideIterator迭代器{}
    //实施2:授权
    pub struct CommissionBookSide,
    {
    底面:B,
    乘数:f64,
    _标记:PhantomData CommissionBookSide,
    {
    新酒吧(基本图书侧:B)->佣金图书侧
    哪里
    B:书边;
    //"前面加了一个,
    fn book_迭代器(&'a self)->self::BookIteratorType{
    委托迭代器{
    base\u迭代器:self.base\u book\u side.book\u迭代器(),
    乘数:自我乘数,
    _标记:PhantomData{},
    }
    }
    }
    发布结构委托迭代器,
    {
    基迭代器:BI,
    乘数:f64,
    _marker:PhantomData迭代器用于CommissionIterator,
    {
    类型Item=BI::Item;
    fn下一步(&mut self)->选项{
    self.base_迭代器
    .next()
    .map(| quote | quote*self.乘数)
    }
    }
    委员迭代器{}的impl
    

    你的问题基本上可以归结为以下几点。这里的问题是什么

    fn图书迭代器{
    //^^^^^^需要是“&”a[f64]`
    slice.iter()
    }
    
    方法
    book\u迭代器(&self)
    返回一个
    book迭代器:迭代器{}
    酒吧和书边;
    //'此处在特征方法签名中添加了一个
    fn book_迭代器(&'a self)->self::BookIteratorType;
    }
    //实现1:有状态
    发布结构ArrayBookSide{
    引用:Vec,
    }
    发布结构ArrayBookSideIterator,
    }
    ArrayBookSide的impl{
    类型BookIterator type=ArrayBookSideIterator迭代器的ArrayBookSideIterator迭代器{}
    //实施2:授权
    pub struct CommissionBookSide,
    {
    底面:B,
    乘数:f64,
    _标记:PhantomData CommissionBookSide,
    {
    新酒吧(基本图书侧:B)->佣金图书侧
    哪里
    B:书边;
    //"前面加了一个,
    fn book_迭代器(&'a self)->self::BookIteratorType{
    委托迭代器{
    base\u迭代器:self.base\u book\u side.book\u迭代器(),
    乘数:自我乘数,
    _标记:PhantomData{},
    }
    }
    }
    发布结构委托迭代器,
    {
    基迭代器:BI,
    乘数:f64,
    _marker:PhantomData迭代器用于CommissionIterator,
    {
    类型Item=BI::Item;
    fn下一步(&mut self)->选项{
    self.base_迭代器
    .next()
    .map(| quote | quote*self.乘数)
    }
    }
    委员迭代器{}的impl
    

    非常感谢!现在它工作了,看起来很简单!我还有一个问题。为什么有必要注释
    self
    ?它在声明中已经用相同的生命周期名称进行了注释,不是吗?看起来像是重复的。声明
    BookIterator非常感谢你!现在它工作了,看起来很简单!我还有一个问题estion。为什么需要注释
    self
    ?声明中已经用相同的生存期名称注释了它,不是吗?看起来像是重复的。声明
    BookIterator
    
    error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in function call due to conflicting requirements
      --> src/main.rs:31:58
       |
    31 |         ArrayBookSideIterator { quotes_iter: self.quotes.iter() }
       |                                                          ^^^^
       |
    note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 30:5...
      --> src/main.rs:30:5
       |
    30 | /     fn book_iterator(&self) -> Self::BookIteratorType {
    31 | |         ArrayBookSideIterator { quotes_iter: self.quotes.iter() }
    32 | |     }
       | |_____^
    note: ...so that reference does not outlive borrowed content
      --> src/main.rs:31:46
       |
    31 |         ArrayBookSideIterator { quotes_iter: self.quotes.iter() }
       |                                              ^^^^^^^^^^^
    note: but, the lifetime must be valid for the lifetime `'a` as defined on the impl at 27:6...
      --> src/main.rs:27:6
       |
    27 | impl<'a> BookSide<'a> for ArrayBookSide {
       |      ^^
    note: ...so that the types are compatible
      --> src/main.rs:30:55
       |
    30 |       fn book_iterator(&self) -> Self::BookIteratorType {
       |  _______________________________________________________^
    31 | |         ArrayBookSideIterator { quotes_iter: self.quotes.iter() }
    32 | |     }
       | |_____^
       = note: expected `BookSide<'a>`
                  found `BookSide<'_>`