function - 如何在函数中使用泛型并在 rust 中使用模式匹配?
问题描述
我正在解决一个名为 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(),
}
}
它不编译,模式匹配不喜欢这样。我是 rust 新手,我试图了解创建一个具有通用类型的函数是否可以解决这个仅以 DRY 方式处理 2 种不同类型的问题,或者我应该坚持简单地为 U128 类型重写函数?
解决方案
我只是假设评论中的大部分内容都已处理,并且您将回到使用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
on&T
,而是 onT
- 所有
Output
类型规范都是这样我们不会隐式更改类型 - 操作T
将始终映射到T
- 我们要求
Eq
,所以我们可以比较余数的结果 - 我们要求
From<u32>
,所以我们可以into()
每一个数字常数
工作版本可以在这里找到
推荐阅读
- android - 在运行时更新 NavDestination 标签
- git - 我正在寻找一个命令来查找修复我的提交的所有提交
- reactjs - 任何使用 Electron.js 的方式
组件到 React.js 应用程序中 - r - R:在用户制作的函数中使用中介时出现未定义的列错误
- dart - 如何在 setState 上更新 webview 的 url?
- python-3.x - 如何修复'TypeError:需要一个类似字节的对象,而不是'元组'''?
- java - 按下向上和向下箭头时,Java FX 无法识别 KeyCode.UP 或 KeyCode.Down (MacBook Pro 18 - Mojave 10.14.5)
- javascript - CkEditor5 - 无法在自定义插件中调用方法并且事件不起作用
- python-3.x - 获取 TypeError:类型集的对象不是 JSON 可序列化的,当尝试通过 REST-API 发布字典时
- base64 - 我已经编码了字符串,但我不知道它是什么类型