如何实现 Rng 和 RngCore 以便对自定义结构类型进行采样?

ter*_*ett 0 random rust

我有以下代码,我尝试在其中实现RngRngCore定义类型。

#[cfg(test)]
use rand::{Rng, RngCore};

pub const FP751_NUM_WORDS: usize = 12;

#[repr(C)]
#[derive(Copy, Clone)]
pub struct Fp751Element(pub (crate) [u64; FP751_NUM_WORDS]);

#[cfg(test)]
impl RngCore for Fp751Element {
    fn next_u64(&mut self) -> u64 {
        self.next_u64()
    }
}

#[cfg(test)]
impl Rng for Fp751Element {
    fn gen<Fp751Element>(&mut self) -> Fp751Element {
        let high_limb = self.next_u64() % 246065832128056;

        Fp751Element([
            self.next_u64(),
            self.next_u64(),
            self.next_u64(),
            self.next_u64(),
            self.next_u64(),
            self.next_u64(),
            self.next_u64(),
            self.next_u64(),
            self.next_u64(),
            self.next_u64(),
            self.next_u64(),
            high_limb
        ])
    }
}
Run Code Online (Sandbox Code Playgroud)

我想实现这些特征,因为我稍后想将其quickcheck::Arbitrary与我的类型一起使用。但是,上面的类型代码在行中抛出以下错误impl Rng for Fp751Element

crate 中的冲突实现rand: - impl rand::Rng for R,其中 R: rand::RngCore, R: ?Sized;

有任何想法吗?

E_n*_*ate 8

tl;dr如果您想生成自己类型的随机值,那么实现这个特性是错误的。

该特征Rng是 的扩展特征RngCore,包含一揽子实现。这意味着所有实现的类型都RngCore已经实现了Rng,并且您不应该尝试自己提供它。一旦Rng进入范围,所有实现都RngCore将提供那里提供的额外方法。

然而:

我想实现这些特征,因为我稍后想将其quickcheck::Arbitrary与我的类型一起使用。

所以这是一个 XY 问题!RngCore旨在创建随机数生成算法,而不是定义如何从随机数源中采样数据类型。

fn gen<Fp751Element>(&mut self) -> Fp751Element {
Run Code Online (Sandbox Code Playgroud)

事实上,给出的方法签名非常具有误导性。在这种情况下,Fp751Element不是您的 struct type Fp751Element,而是一个具有相同名称的新泛型参数类型!

为了使用您自己的发行版实现您自己的类型的生成,请提供自定义Distribution实现。

fn gen<Fp751Element>(&mut self) -> Fp751Element {
Run Code Online (Sandbox Code Playgroud)

完成此操作后,将使用以下命令生成您类型的新值sample

let mut rng = thread_rng();
let elem: Fp751Element = rng.sample(Fp751UniformDist);
Run Code Online (Sandbox Code Playgroud)

也可以看看: