我刚刚深入研究了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
}
Run Code Online (Sandbox Code Playgroud)
那么将会对我来说,能够通过isize,i64,usize,等作为参数?我已经阅读了主页上的Rust指南,但我不确定如何将特征的想法应用到我的目标中.
Chr*_*gan 25
通用数字类型可能会非常麻烦,但是一旦你掌握了它们,它们就不会太糟糕,虽然更加冗长.该标准积木这样的方法是在特质的num箱子从crates.io,最值得注意的是Num,Zero和One,以及标准库的std::cmp::PartialOrd.
数字文字不能超过任何数字类型; 它们必须用特征方法调用完成; Zero::zero()并且One::one()足以满足大多数目的 - 这里我们想要的数字是0,1,2,3,5和6,这些构建块可以显着地实现.您也可以使用静态方法创建自己的特性来生成这些值,并为您喜欢的任何数字类型实现它,但是使用保证Num的更好的想法来实现它.
基本过程是将您的泛型类型参数指定为基于Num(并且PartialOrd如果您在该类型的值上写出不等式,例如i * i <= n),并将任何数字文字替换为从0和1构造的数字文字,作为此处的半打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
}
Run Code Online (Sandbox Code Playgroud)
小智 15
要添加到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();
Run Code Online (Sandbox Code Playgroud)