我正在解决一个名为Syracuse问题(3n + 1问题)的数学问题。
我想让我的函数适用于2种类型,一种是u64,另一种是通过包含2个我称为U128的u64来扩展u64大小的结构。
我的u64函数看起来像这样
fn syracuse(n: u64) -> u64 {
match n % 2 {
0 => n / 2,
1 => 3 * n + 1,
_ => 1,
}
}
我已经尝试对U128和u64实现特征。
fn syracuse<T>(n: T) -> T where T : Add +Mul+Div+Rem + Basic0123 {
match n % Basic0123::two() {
Basic0123::zero() => n / Basic0123::two(),
Basic0123::one() => Basic0123::three() * n + Basic0123::one(),
_ => Basic0123::one(),
}
}
它不能编译,模式匹配不是这样。我是锈病的新手,我试图了解使用泛型类型创建函数是否可以解决这个仅以DRY方式处理2种不同类型的问题,或者我应该坚持简单地为U128类型重写函数吗? / p>
答案 0 :(得分:2)
我只是假定注释中的大多数内容都已处理完毕,您将返回使用std::u128
基本类型而不是您自己的类型。
对泛型类型实现Syracuse猜想的正确方法如下:
fn syracuse<T>(n: T) -> T
where T : Copy + Eq + Add<Output = T> + Mul<Output = T> + Div<Output = T> + Rem<Output = T> + From<u32> {
let zero:T = 0.into();
match n % 2.into() == zero {
true => n/(2.into()),
false => n * (3.into()) + 1.into()
}
}
按出现顺序:
Copy
是必需的,因为我们不需要Rem
上的&T
,而是T
上的Output
类型规范都是这样,因此我们不会隐式更改类型-对T
的操作将始终映射到T
Eq
,以便我们可以比较其余部分的结果From<u32>
,因此我们可以into()
每个单个数字常量可以找到有效的版本here