我试图编写一个函数,它接受一段数字并计算平均值。
我尝试使用泛型类型均值函数的实现的想法,但得到了一个错误。
我的代码是:
extern crate num;
use num::{FromPrimitive, Zero};
use std::ops::{Add, Div};
fn main() {
let mut numbers = [10, -21, 15, 20, 18, 14, 18];
let err = "Slice is empty.";
println!("Mean is {:.3}", mean(&numbers).expect(err));
}
fn mean<T>(numbers: &[T]) -> Option<f64>
where
T: Copy + Zero + Add<T, Output = T> + Div<T, Output = T> + FromPrimitive,
{
match numbers.len() {
0 => None,
_ => {
let sum = numbers.iter().sum: ();
let length = FromPrimitive::from_usize(numbers.len()).unwrap();
Some(sum / length)
}
}
}错误是:
error[E0658]: type ascription is experimental (see issue #23416)
--> src/main.rs:20:23
|
20 | let sum = numbers.iter().sum: ();
| ^^^^^^^^^^^^^^^^^^^^^^在不使用实验特性的情况下,是否有编写通用均值函数的方法?
发布于 2019-01-15 09:22:20
这个怎么样:
use std::iter::Sum;
fn main() {
let err = "Slice is empty.";
// Test vector of integers
let numbers = vec![10i32, -21, 15, 20, 18, 14, 18];
println!("Mean is {:.3}", mean(numbers.into_iter()).expect(err));
// Test vector of floating point numbers
let numbers = vec![10f64, -21f64, 15f64, 20f64, 18f64, 14f64, 18f64];
println!("Mean is {:.3}", mean(numbers.into_iter()).expect(err));
// Test empty vector
let numbers: Vec<i32> = Vec::new();
println!("Mean is {:.3}", mean(numbers.into_iter()).expect(err));
}
fn mean<T, I: Iterator<Item = T>>(iter: I) -> Option<f64>
where
T: Into<f64> + Sum<T>,
{
let mut len = 0;
let sum = iter
.map(|t| {
len += 1;
t
})
.sum::<T>();
match len {
0 => None,
_ => Some(sum.into() / len as f64)
}
}与迄今公布的答案相比,它似乎具有以下优点:
num箱。FromPrimitive和Zero这样难以猜测的特征。或与上面的版本有以下区别的版本:
use std::iter::Sum;
fn main() {
let err = "Slice is empty.";
// Test aray of integers
let numbers = [10, -21, 15, 20, 18, 14, 18];
println!("Mean is {:.3}", mean(numbers.iter()).expect(err));
// Test array of floating point numbers
let numbers = [10f64, -21f64, 15f64, 20f64, 18f64, 14f64, 18f64];
println!("Mean is {:.3}", mean(numbers.iter()).expect(err));
// Test empty array
let numbers: [i32; 0] = [];
match mean(numbers.iter()) {
Some(mean_) => println!("Mean is {:.3}", mean_),
None => println!("Empty array"),
}
}
fn mean<'a, T, I>(iter: I) -> Option<f64>
where
T: Into<f64> + Sum<&'a T> + 'a,
I: Iterator<Item = &'a T>,
{
let mut len = 0;
let sum = iter
.map(|t| {
len += 1;
t
})
.sum::<T>();
match len {
0 => None,
_ => Some(sum.into() / len as f64),
}
}感谢我的朋友斯文的代码贡献。
发布于 2019-01-13 12:39:25
在泛型函数中执行两种不同的操作:
Sum<T>边界来告诉元素是可加的。f64或任何要限制的浮点类型。由于您使用的是num机箱,所以我添加了ToPrimitive作为边界,这告诉您可以将泛型类型转换为基本类型。以下是实现:
fn mean<'a, T: 'a>(numbers: &'a [T]) -> Option<f64>
where
T: ToPrimitive + Sum<&'a T>,
{
match numbers.len() {
0 => None,
_ => {
let sum = numbers.iter().sum::<T>();
let length = f64::from_usize(numbers.len())?;
T::to_f64(&sum).map(|sum| sum / length)
}
}
}发布于 2019-01-13 13:49:33
其他答案可能会帮助您解决编写此函数的实际问题。
但是,您询问的实际错误只是语法错误。你写了这个:
let sum = numbers.iter().sum: ();但几乎可以肯定地说:
let sum = numbers.iter().sum();编译器看到了意外包含的:,并认为您正在尝试使用类型归属。类型归属是在表达式中使用类型注释的语法,而不是仅在变量声明中使用类型注释。
您所写的内容非常类似于:
let sum: () = numbers.iter().sum;如果要在夜间的rustc构建中启用类型归属,则错误会发生变化,因为现在编译器将告诉您sum是一个函数,并且肯定没有()类型。
https://stackoverflow.com/questions/54168352
复制相似问题