如何允许函数使用整数或浮点数?

ato*_*her 5 rust

发现了一个计算均值的函数,并且一直在使用它.下面的代码片段会运行,但如果输入中的数据从float变为int,则会发生错误.如何使用浮点数和整数?

use std::borrow::Borrow;

fn mean(arr: &mut [f64]) -> f64 {
    let mut i = 0.0;
    let mut mean = 0.0;
    for num in arr {
        i += 1.0;
        mean += (num.borrow() - mean) / i;
    }
    mean
}

fn main() {
    let val = mean(&mut vec![4.0, 5.0, 3.0, 2.0]);
    println!("The mean is {}", val);
}
Run Code Online (Sandbox Code Playgroud)

use*_*342 10

问题中的代码无法编译,因为f64没有borrow()方法.此外,它接受的切片不需要是可变的,因为我们没有改变它.这是一个编译和工作的修改版本:

fn mean(arr: &[f64]) -> f64 {
    let mut i = 0.0;
    let mut mean = 0.0;
    for num in arr.iter() {
        i += 1.0;
        mean += (num - mean) / i;
    }
    mean
}
Run Code Online (Sandbox Code Playgroud)

要接受整数,函数必须是通用的.理想情况下,它不仅可以接受整数,还可以接受任何可以转换为的类型f64,例如f32用户提供的数据类型.写下这样的东西会很好:

fn mean<T>(arr: &[T]) -> f64 {
    let mut i = 0.0;
    let mut mean = 0.0;
    for num in arr.iter() {
        i += 1.0;
        mean += (num as f64 - mean) / i;
    }
    mean
}
Run Code Online (Sandbox Code Playgroud)

这不会编译,因为x as f64没有为任意定义x.相反,我们需要一个特征绑定,T它定义了一种将T值转换为的方法f64.这正是这个Into特质的目的; T实现的每个类型都Into<U>定义了一个into(self) -> U方法.指定T: Into<f64>为特征绑定为我们提供了into()返回的方法f64.

我们还需要请求TCopy,让锈知道数组中的值将不会被转换"花"(移动).由于整数实现Copy,这对我们来说没问题.然后工作代码如下所示:

fn mean<T: Into<f64> + Copy>(arr: &[T]) -> f64 {
    let mut i = 0.0;
    let mut mean = 0.0;
    for num in arr.iter() {
        i += 1.0;
        mean += ((*num).into() - mean) / i;
    }
    mean
}

fn main() {
    let val1 = mean(&vec![4.0, 5.0, 3.0, 2.0]);
    let val2 = mean(&vec![4, 5, 3, 2]);
    println!("The means are {} and {}", val1, val2);
}
Run Code Online (Sandbox Code Playgroud)

请注意,这仅适用于定义无损转换的类型f64.因此,它会为工作u32,i32(如在上面的例子)和更小的整数类型,但它不会接受例如向量i64u64,不能无损地转化成f64.

还要注意,这个问题很好地适用于函数式编程习惯用法,如enumerate()fold().尽管在这个已经很长的答案的范围之外,写出这样的实现是一种难以抗拒的练习.

  • 这是合理的,我只喜欢“全面披露”。好答案:) (2认同)