rust 在结构初始化中生成并存储闭包

tkclm6bt  于 2023-02-23  发布在  其他
关注(0)|答案(1)|浏览(135)

是否可以在结构体中生成并存储闭包:当前正在获取类型不匹配的错误

pub struct MM<F>
where
    F: Fn(&f64, &f64) -> f64,
{
    pub n: f64, //
    pub y: f64, //
    p: f64,     // the p parameter associated with prior probability
    f: F,       // this must only take two arguments
}

impl<F> MM<F>
where
    F: Fn(&f64, &f64) -> f64,
{
    pub fn new(l: f64, prior: f64) -> Self {
        let func = |a: &f64, b: &f64| -> f64 { b.powf(prior) * a };
        MM {
            n: l,
            y: l,
            p: prior,
            f: func,
        }
    }
}
h79rfbju

h79rfbju1#

我对你发布的代码做了一些调整。主要是我改变了new的返回类型(see explanation here解释了为什么这是必要的)。我还在new的结构体创建中将CFMM改为MM,看起来像是一个打字错误。
简短的版本为不耐烦:你不能从new返回Self并在里面放一个闭包,编译器会告诉你
每个闭包都有不同的类型,因此无法始终匹配参数F的**调用方选择的类型
这里的关键元素是“caller-chosed”。Rust不能保证我们在new中构造的闭包将匹配调用者决定的F应该是什么。一旦你让new显式地决定它将返回什么impl Fn(...),它就工作了。
here也有更多的解释。

pub struct MM<F: Fn(&f64, &f64) -> f64> {
    pub n: f64,
    pub y: f64,
    pub p: f64,     // the p parameter associated with prior probability
    pub f: F,       // this must only take two arguments
}

pub fn new_mm(l: f64, prior: f64) -> MM<impl Fn(&f64, &f64) -> f64> {
    let func = move |a: &f64, b: &f64| -> f64 { b.powf(prior) * a };
    MM {
        n: l,
        y: l,
        p: prior,
        f: func,
    }
}

fn main() {
    let a: f64 = 1.0;
    let b: f64 = 0.9;
    let p  = new_mm(a, b);
    println!("{}", (p.f)(&1.0, &2.0));
}

Playground

相关问题