Если я хотел бы реализовать is_even
я, очевидно, начать с реализации is_divisible
, который является более общим:
#![feature(zero_one)]
use std::cmp;
use std::num;
use std::ops;
fn is_divisible<T>(x: T, by: T) -> bool
where T: ops::Rem<Output = T> + num::Zero + cmp::PartialEq
{
(x % by) == T::zero()
}
кажется достаточно легко.
Однако is_even
имеет еще больше ограничений, и это становится немного долго, так что давайте следовать СУХОЙ:
trait Arithmetic:
From<u8> +
cmp::PartialEq + cmp::Eq + cmp::PartialOrd + cmp::Ord +
ops::Add<Self, Output = Self> + ops::Sub<Self, Output = Self> +
ops::Mul<Self, Output = Self> + ops::Div<Self, Output = Self> + ops::Rem<Self, Output = Self> {}
impl<T> Arithmetic for T
where T: From<u8> +
cmp::PartialEq + cmp::Eq + cmp::PartialOrd + cmp::Ord +
ops::Add<T, Output = T> + ops::Sub<T, Output = T> +
ops::Mul<T, Output = T> + ops::Div<T, Output = T> + ops::Rem<T, Output = T>
{}
Хорошо, эта черта должна охватывать нас. Имейте в виду, что он не связан с ops::Neg
, потому что эта граница не реализована для неподписанных признаков; поэтому, если нам нужно Neg
, мы должны добавить его; но это достаточно легко.
Что касается вопроса о константах, ну, действительно, ваш путь от zero
вверх безумный. Именно по этой причине черты Zero
и One
по-прежнему нестабильны.
Общие признаки конвертации: convert::From
и convert::Into
, и это то, что можно было бы использовать.
Так давайте переформулировать is_divisible
, и, наконец, реализовать is_even
:
fn is_divisible<T>(x: T, by: T) -> bool
where T: Arithmetic
{
(x % by) == 0.into()
}
fn is_even<T>(x: T) -> bool
where T: Arithmetic
{
is_divisible(x, 2.into())
}
И действительно, эти две функции, кажется, и совершенно ясно, в то время еще родовым.
Full code here
Теперь мы можем утверждать, что создание этой Arithmetic
черты является многословно способом добраться до is_even
. Это.Однако:
- , если вам нужно только
is_even
, очевидно, вам мало что нужно, если требуется 6 границ; это один от
- , если вам необходимо иметь несколько обобщенных функции, работающие на числовых значениях, то небольшая стоимость создания этого признака и функции пренебрежимо мала в великой схеме вещей
Короче говоря, это работает. И это действительно не так обременительно.
Это не похоже на узкоцелевый вопрос, на который может ответить Stack Overflow. «Как реализовать общий алгоритм» является * чрезвычайно широкой темой. Ваш код, как написано, выглядит как определение факториала, как я ожидал. * Для меня *, ваш вопрос читает больше напыщенности, чем полезный вопрос, но это, скорее всего, только моя личная интерпретация. – Shepmaster
@Shepmaster Если 'factorial' выглядит, как насчет этого' is_even'? – Adam
Вы можете уменьшить границы, используя черты в [num crate] (https://github.com/rust-num/num), но реализации останутся прежними. Как вы ожидаете, что общая реализация is_even будет выглядеть идеально? –