【问题标题】:Is there a trait that works for both VecDeque and Vec?是否有适用于 VecDeque 和 Vec 的特征?
【发布时间】:2020-09-29 16:25:35
【问题描述】:

我们可以将Vec<f64> 传递给这个函数,但我们不能传递VecDeque,因为那是两个切片:

fn mean(v: &[f64]) -> f64 {
    let sum = v.iter().sum();
    sum / v.len() as f64
}

是否有一个特征,可能类似于 C++ RandomAccessContainer,它允许我们一般地编写在 VecVecDeque 上运行的代码?

【问题讨论】:

标签: rust traits random-access


【解决方案1】:

您可以只链接特征,例如 Index<usize, Output = f64> 以获取索引处的元素,IntoIterator<Item = &f64> 以使用 IntoIterator。如果您需要len,那么您可以制作自己的 trait 并实现它。

【讨论】:

【解决方案2】:

有两种方法:

  1. 让您的函数接受切片:fn mean(&[&[f64]]) -> f64。 可以叫mean(&[v.as_slice()])
  2. 让它接受Iterator。我认为这是允许同时使用VecDequeVec 的最可接受的方式:
use std::collections::VecDeque;
use std::iter::Iterator;
use std::vec::Vec;

fn mean<T: Iterator<Item = f64>>(iter: T) -> f64 {
    let (last_index, sum) = iter
        .enumerate()
        .fold((0, 0.0), |(_, sum), (i, v)| (i, sum + v));
    sum / (last_index as f64 + 1.0)
}

fn main() {
    let v: Vec<f64> = vec![0.0, 1.0, 2.0, 3.0, 4.0];
    println!("{:?}", mean(v.iter().copied()));
    let v: VecDeque<f64> = v.into();
    println!("{:?}", mean(v.iter().copied()));
}

【讨论】:

    【解决方案3】:

    相信你可以使用Iterator作为参数。

    有一个很好的article 关于迭代器的使用。

    【讨论】:

      【解决方案4】:

      在这些情况下,有一种替代方法值得考虑, 而不是寻找类型 A 和 B 都实现的特征 可以传递给您的函数,您创建一个既支持的新特征,又使用您的新特征而不是函数。它通常意味着一些重复和样板,但以后可以很好地扩展。

      trait HasMeanF64 {
          fn mean(&self) -> f64;
      }
      
      impl HasMeanF64 for &[f64] {
          fn mean(&self) -> f64 {
              self.iter().sum::<f64>() / self.len() as f64
          }
      }
      
      impl HasMeanF64 for Vec<f64> {
          fn mean(&self) -> f64 {
              self.iter().sum::<f64>() / self.len() as f64
          }
      }
      
      impl HasMeanF64 for VecDeque<f64> {
          fn mean(&self) -> f64 {
              self.iter().sum::<f64>() / self.len() as f64
          }
      }
      

      现在你可以写v.mean(),而不是写mean(v)

      如果你仍然想要你的mean(v) 表格,你可以写

      fn mean<T: HasMeanF64>(v: &T) -> f64 {
          v.mean()
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-10-02
        • 1970-01-01
        • 2020-02-29
        • 1970-01-01
        • 2012-06-24
        • 1970-01-01
        相关资源
        最近更新 更多