Реализация средней функции для общих типов
Я пытаюсь написать функцию, которая возвращает среднее значение Vector
. Я хочу, чтобы он работал с универсальными типами, но у меня возникли некоторые трудности при его реализации.
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()
- это usize
а sum
типа 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. Как я должен идти об этом?
Эти типы примитивов реализовать в FromPrimitive
признак, определенном в в num
клети, чтобы позволить преобразование между примитивными типами, в том числе 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()
}
}