如何创建对各种整数类型通用的 is_prime 函数? [英] How can I create an is_prime function that is generic over various integer types?

查看:24
本文介绍了如何创建对各种整数类型通用的 is_prime 函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚深入研究了 Rust 并想要创建一些通用的基本数学函数.我有以下 is_prime 函数:

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
}

我需要什么才能将 isizei64usize 等作为参数传递?我已经通读了主页上的 Rust 指南,但我不确定如何将特征的想法应用到我的目标在这里.

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.

推荐答案

使用泛型数字类型可能会很麻烦,但是一旦掌握了它们,它们就不会太糟糕,尽管有点更详细.此类方法的标准构建块是来自 crates 的 num crate 中的特征.io,最值得注意的是 Num, One,以及标准库的 std::cmp::PartialOrd.

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.

数字文字不能对任何数字类型通用;它们必须通过 trait 方法调用来完成;Zero::zero()One::one() 可以满足大多数用途——这里我们想要的数字是 0、1、2、3、5 和 6,这些数字可以通过这些构建块来实现.您也可以使用产生这些值的静态方法创建自己的 trait,并为您喜欢的任何数字类型实现它,但仅使用 Num 保证的内容来实现它是一个更好的主意.

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.

基本过程是将泛型类型参数指定为基于 Num(以及 PartialOrd,如果您在该类型的值上编写不等式,例如 i * i <= n),并将任何数字文字替换为由 0 和 1 构成的数字文字,如下面方法开头的半打 let 语句所示.这通常就足够了.

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
}

这篇关于如何创建对各种整数类型通用的 is_prime 函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆