当前位置: 首页 > 知识库问答 >
问题:

实现泛型类型的均值函数

邓丰
2023-03-14

我试图编写一个函数来返回向量的平均值。我希望它能与泛型类型一起工作,但我在实现它时遇到了一些困难。

extern crate num; // 0.2.0

use num::Zero;
use std::ops::{Add, Div};

pub struct Vector<T> {
    pub size: usize,
    pub data: Vec<T>,
}

impl<T: Copy + Zero + Add<T, Output = T>> Vector<T> {
    pub fn sum(&self) -> T {
        self.data.iter().fold(T::zero(), |sum, &val| sum + val)
    }
}

impl<T: Copy + Zero + Add<T, Output = T> + Div<T, Output = T>> Vector<T> {
    pub fn mean(&self) -> T {
        let sum = self.sum();
        sum / self.data.len()
    }
}

操场。

上面的例子没有编译为self.data.len()是一个usizesum是类型T

error[E0308]: mismatched types
  --> src/lib.rs:20:15
   |
20 |         sum / self.data.len()
   |               ^^^^^^^^^^^^^^^ expected type parameter, found usize
   |
   = note: expected type `T`
              found type `usize`

我知道我可以将签名更改为:

impl<T: Copy + Zero + Add<T, Output = T> + Div<usize, Output = T>> Vector<T>

它将编译-但这不是为Rust基元类型实现的。我该怎么做呢?


共有2个答案

贺聪
2023-03-14

在许多情况下,计算输入类型的平均值是没有意义的。例如,整数1和2的整数平均值为1。如果您希望能够获得任何迭代器值的平均值,这些值可以被视为i64,并将平均值作为f64,您可以使用迭代器::sum和进入

fn avg_iter<I>(s: I) -> f64
where
    I: IntoIterator,
    I::Item: Into<i64>,
{
    let mut count = 0;
    let total = s
        .into_iter()
        .map(Into::into)
        .inspect(|_| count += 1)
        .sum::<i64>();
    total as f64 / count as f64
}

一些例子:

use std::collections::VecDeque;

fn main() {
    let a: Vec<u16> = vec![1, 2, 3];
    let b: Vec<u32> = vec![1, 2, 3];
    let c: VecDeque<u16> = vec![1u16, 2, 3].into();

    let v = avg_iter(a.iter().cloned());
    println!("{}", v);
    let v = avg_iter(a);
    println!("{}", v);

    let v = avg_iter(b.iter().cloned());
    println!("{}", v);
    let v = avg_iter(b);
    println!("{}", v);

    let v = avg_iter(c.iter().cloned());
    println!("{}", v);
    let v = avg_iter(c);
    println!("{}", v);
}

柯乐童
2023-03-14

基本类型实现了num板条箱中定义的FromPrimitive特性,以允许在基本类型之间进行转换,包括usize。我们可以在函数上添加一个FromPrimitive绑定,然后我们可以将usize转换为T

extern crate num; // 0.2.0

use num::{FromPrimitive, Zero};
use std::ops::{Add, Div};

impl<T> Vector<T>
where
    T: Copy + Zero + Add<T, Output = T> + Div<T, Output = T> + FromPrimitive,
{
    pub fn mean(&self) -> T {
        let sum = self.sum();
        sum / FromPrimitive::from_usize(self.data.len()).unwrap()
    }
}
 类似资料:
  • 我被分配了一个问题:编写一个通用的加权元素 到目前为止,我已经创建了类并实现了Compariable,但在为W创建compareTo()方法时遇到了问题。我有: 我遇到的问题是,当我比较权重时,没有找到数据的权重。还有没有其他我必须创建的方法来正确地拥有一个在其中一个变量上实现可比较的类?谢谢你的帮助

  • 我试图约束泛型函数的返回类型。(为了简化示例,请忽略函数的实际“有用性”)。 但是返回语句会导致打字错误- -这让我很困惑。在我的理解中,

  • 我正在尝试一个非常基本(人为)的条件类型函数,但遇到了意外错误: 我认为这是一个非常简单的条件类型用法,所以不确定发生了什么。有什么想法吗?

  • 编译时,此代码将产生以下+错误: 问题是访问中的类型T与列表中的T不相同。如何修复此编译问题?

  • 问题内容: 我的问题是这样的: 为什么不能使用类Class的new T()和newInstance()实例化泛型? 问题答案: 您需要使用反射(),因为在编译时需要链接其构造函数的类是未知的。因此,编译器无法生成链接。