I just took the dive into Rust and want to make some basic math functions that are generic. I have the following is_prime
function:
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 }
What would it take for me to be able to pass isize
, i64
, usize
, etc. as arguments? I have read through the Rust guide on the homepage but I am not certain how to apply the ideas of traits to my goal here.
Generic number types can be quite a nuisance to work with, but once you get the hang of them they don’t tend to be too bad, though a little more verbose. The standard building blocks to such methods are the traits in the num
crate from crates.io, most notably Num
, Zero
and One
, as well as the standard library's std::cmp::PartialOrd
.
Numeric literals cannot be generic over any numeric type; they must be done with a trait method call; Zero::zero()
and One::one()
will suffice for most purposes—here the numbers that we want are 0, 1, 2, 3, 5 and 6, which are eminently achievable with these building blocks. You could also make your own trait with static methods producing these values and implement it for whatever numeric types you like, but doing it with just what’s guaranteed by Num
is a better idea.
The basic procedure is to specify your generic type parameters as being based on Num
(and PartialOrd
if you write inequalities on values of that type, such as i * i <= n
), and replace any numeric literals with ones constructed from zero and one, as the half dozen let
statements at the start of the method below demonstrates. That will normally be enough.
Here’s what you end up with for this particular method:
// 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 }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With