【问题标题】:Expanding a VecDeque to limit size扩展 VecDeque 以限制大小
【发布时间】:2020-09-26 11:18:22
【问题描述】:

我想实现一个具有最大大小限制的 VecDeque。我有两个策略,但我都无法完成。

第一种方法:通过组合继承。

我创建了一个新结构:

pub struct LimVecDeque<T> {                                                                                                    
     deque: VecDeque<T>,                                                 
     limit: usize,                                                       
}

并创建一个新的推送功能:

impl<T> LimVecDeque<T> {
  ...

  pub fn push (&self, elem: T) {
    self.deque.push_back(elem);
    if self.limit < self.deque.len() {
      self.deque.pop_front();
    }
  }

  ...
}

这可行,但是随着我的程序长大,我需要向我的 LimVecDeque 结构添加功能。其中大部分是原始 VecDeque 的副本:

pub fn len(&self) -> usize {
  self.deque.len()
}

我在导出 VecDeque::iter() 时遇到更多问题。我遇到了类型和迭代器的问题(我对迭代器还不是很好)。 这种方法迫使我将 VecDeque 中的每个函数克隆/导出到 LimVecDeque。很多工作!

第二种方法:为 VecDeque 创建一个新的 trait 并实现:

trait Limited {
  type Elem;

  pub fn push_bounded(&self, limit: usize, elem: Elem);
}

然后用 VecDeque 实现 trait。

但我必须在每次插入时传递 limit 值。一次怎么能通过极限值?

一般来说,从 std 向结构添加功能的简单方法是什么(不丢失/隐藏当前功能)?

【问题讨论】:

    标签: collections rust extends


    【解决方案1】:

    正如 edkeveked 的回答所指出的,有一个可用的 crate (BoundedVecDequeue),它实现了您尝试实现的确切情况。

    如果你查看BoundedVecDequeue 的实现,你会发现它使用了你描述的第一个模式:在需要修改被包装类型的行为的地方创建包装方法,并在它所在的地方委托方法调用不是。

    正如您所指出的,这可能会导致大量样板文件。为了减少所涉及的工作量,您可能想尝试delegate crate,它添加了一个为您执行委托的宏:

    use delegate::delegate;
    
    impl<T> LimVecDeque<T> {
        delegate! {
            to self.inner {
    
                pub fn len(&self) -> usize;
                pub fn truncate(&mut self, new_len: usize);
                pub fn as_mut_slices(&mut self) -> (&mut [T], &mut [T]);
                // etc
            }
        }
    
        // ...
    
    }
    

    警告:我自己还没有真正使用过这个箱子,所以我不能保证它的质量。

    【讨论】:

      【解决方案2】:

      BoundedVecDeque 就是这样做的

      use ::bounded_vec_deque::BoundedVecDeque;
      
      fn main() {
          let mut a = BoundedVecDeque::new(2);
          a.push_front(2);
          a.push_front(3);
          a.push_front(4);
          println!("{:?}", a); //4, 3
      }
      

      【讨论】:

        猜你喜欢
        • 2011-05-20
        • 2021-06-08
        • 1970-01-01
        • 2018-11-03
        • 2023-03-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-09
        相关资源
        最近更新 更多