web-dev-qa-db-ja.com

さまざまな整数型に共通するis_prime関数を作成するにはどうすればよいですか?

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
}

isizei64usizeなどを引数として渡すことができるようになるには何が必要ですか?ホームページの 錆ガイド を読みましたが、ここでの目標に特性のアイデアを適用する方法がわかりません。

30
gaigepr

一般的な数値タイプは、操作するのが非常に面倒な場合がありますが、一度コツをつかめば、もう少し冗長ではありますが、それほど悪くはない傾向があります。このようなメソッドの標準的な構成要素は、crates.ioの num crate の特性であり、特に NumZero および One 、および標準ライブラリの _std::cmp::PartialOrd_

数値リテラルは、どの数値型に対してもジェネリックにすることはできません。それらは、トレイトメソッド呼び出しで実行する必要があります。 Zero::zero() および One::one() は、ほとんどの目的に十分です。ここで必要な数は0、1、2、3です。これらのビルディングブロックで非常に達成可能な5および6。これらの値を生成する静的メソッドを使用して独自の特性を作成し、それを好きな数値タイプに実装することもできますが、Numによって保証されているものだけでそれを行うことをお勧めします。

基本的な手順は、ジェネリック型パラメーターをNum(および_i * i <= n_などのその型の値に不等式を書き込む場合はPartialOrd)に基づくものとして指定し、以下のメソッドの開始時の半ダースのletステートメントが示すように、0と1から構成される数値リテラル。通常はそれで十分です。

この特定の方法で最終的に得られるものは次のとおりです。

_// 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
}
_
25
Chris Morgan

Chris Morganの回答に追加するには、num::NumCast::fromを使用して、ZeroOneの使用が不適切な一般的な数値タイプにキャストできます。あなたの場合:

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();
15
user1890753