Реализация средней функции для общих типов

87
10

Я пытаюсь написать функцию, которая возвращает среднее значение 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. Как я должен идти об этом?

спросил(а) 2021-01-19T16:13:57+03:00 2 месяца, 3 недели назад
1
Решение
105

Эти типы примитивов реализовать в 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()
}
}

ответил(а) 2021-01-19T16:13:57+03:00 2 месяца, 3 недели назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема