如何创建对各种整数类型通用的 is_prime 函数?
Posted
技术标签:
【中文标题】如何创建对各种整数类型通用的 is_prime 函数?【英文标题】:How can I create an is_prime function that is generic over various integer types? 【发布时间】:2015-01-04 19:24:12 【问题描述】:我刚刚深入研究了 Rust,并想制作一些通用的基本数学函数。我有以下is_prime
函数:
fn is_prime(n: i64) -> bool
if n == 2 || n == 3
return true;
else if n % 2 == 0 || n % 3 == 0
return false;
let mut i = 5i64;
let mut w = 2i64;
while i*i <= n
if n % i == 0
return false;
i += w;
w = 6 - w;
true
我需要什么才能将isize
、i64
、usize
等作为参数传递?我已经阅读了主页上的Rust guide,但我不确定如何将特质的想法应用到我的目标中。
【问题讨论】:
【参考方案1】:使用通用数字类型可能会很麻烦,但是一旦您掌握了它们,它们就不会太糟糕,尽管有点冗长。这些方法的标准构建块是来自 crates.io 的 the num
crate 中的特征,最值得注意的是 Num
、Zero
和 One
,以及标准库的 std::cmp::PartialOrd
。
数字字面量不能泛型于任何数字类型;它们必须通过 trait 方法调用来完成; Zero::zero()
和 One::one()
足以满足大多数用途——我们想要的数字是 0、1、2、3、5 和 6,这些数字可以通过这些构建块实现。您还可以使用生成这些值的静态方法创建自己的特征,并为您喜欢的任何数字类型实现它,但只使用 Num
保证的内容是一个更好的主意。
基本过程是将泛型类型参数指定为基于Num
(以及PartialOrd
,如果你在该类型的值上写不等式,例如i * i <= n
),并将任何数字文字替换为构造的文字从零到一,正如下面方法开头的半打 let
语句所示。这通常就足够了。
以下是这个特定方法的最终结果:
// You’ll also need the appropriate dependencies.num addition to Cargo.toml
extern crate num;
use num::Num;
fn is_prime<N: Num + PartialOrd + Copy>(n: N) -> bool
let _0 = N::zero();
let _1 = N::one();
let _2 = _1 + _1;
let _3 = _2 + _1;
let _5 = _2 + _3;
let _6 = _3 + _3;
if n == _2 || n == _3
return true;
else if n % _2 == _0 || n % _3 == _0
return false;
let mut i = _5;
let mut w = _2;
while i * i <= n
if n % i == _0
return false;
i = i + w;
w = _6 - w;
true
【讨论】:
不使用Num
trait 作为约束,也可以使用实际需要的基本特征:N: PartialEq + PartialOrd + Add<N, N> + Sub<N, N> + Mul<N, N> + Rem<N, N> + One + Zero
。 Num
只是一个方便的快捷方式。【参考方案2】:
要添加到 Chris Morgan 的答案,您可以使用 num::NumCast::from
转换为不适合使用 Zero
和 One
的通用数字类型。在你的情况下:
use num::Num, NumCast;
fn is_prime<N: Num + Ord + NumCast + Copy>(n: N) -> bool
let _0: N = NumCast::from(0usize).unwrap();
let _1: N = NumCast::from(1usize).unwrap();
let _2: N = NumCast::from(2usize).unwrap();
let _3: N = NumCast::from(3usize).unwrap();
let _4: N = NumCast::from(4usize).unwrap();
let _5: N = NumCast::from(5usize).unwrap();
let _6: N = NumCast::from(6usize).unwrap();
【讨论】:
以上是关于如何创建对各种整数类型通用的 is_prime 函数?的主要内容,如果未能解决你的问题,请参考以下文章