我应该只将 Fn、FnMut 和 FnOnce 用于闭包吗?

Should I use Fn, FnMut and FnOnce only for closures?

提问人:quant_dev 提问时间:11/21/2022 最后编辑:quant_dev 更新时间:11/21/2022 访问量:178

问:

场景:我想编写一个以单变量函数为参数的优化器算法。我希望它既能与闭包一起使用,又能实现一些方法来计算优化函数的值。我是否应该声明我的优化器接受一个参数或其他一些特征,这些特征将由我想传递给优化器的任何结构实现?FnMut

Rust 函数编程 闭包

评论

1赞 isaactfa 11/21/2022
这与函数接受多少参数无关,而是函数以何种方式捕获其环境。s 通过共享引用捕获其环境或根本不捕获其环境(这使得每个 a ),s 可以通过可变引用捕获其环境,并且 s 可能会将值移出其环境并移入闭包。除此之外,不要通过引用来获取闭包,而是通过值来获取它们。对闭包的引用将自动实现闭包的特征。FnfnFnFnMutFnOnce
0赞 quant_dev 11/21/2022
这就是我现在想问的,但我看到我需要更清楚地表达我的问题。我会试着改写它。
0赞 quant_dev 11/21/2022
希望这更清楚......
1赞 isaactfa 11/21/2022
您(还)不能在稳定的 Rust 上自己实现 Fn 特征(跟踪问题)。您可能应该定义自己的特征来执行计算,然后您可以为您的结构和实现(或)的任何类型实现该特征。FnFnMut
1赞 isaactfa 11/21/2022
我会把它作为答案发布。

答:

2赞 isaactfa 11/21/2022 #1

您还不能在稳定的 Rust 上自己实现 Fn 特征。您可能应该定义自己的特征来执行计算,然后您可以为您的结构体和实现 Fn(或 FnMut)的任何类型实现这些特征:

// I'm opting for `&mut self` here as it's more general
// but this might not be necessary for your use case
trait Calculate<T, U> {
    fn calculate(&mut self, t: T) -> U;
}

// Because `Fn: FnMut` this will also implement `Calculate` for `Fn`.
impl<F, T, U> Calculate<T, U> for F
where F: FnMut(T) -> U {
    fn calculate(&mut self, t: T) -> U {
        (self)(t)
    }
}

struct State {
    flag: bool,
}
impl<T, U> Calculate<T, U> for State
where T: Into<U> {
    fn calculate(&mut self, t: T) -> U {
        self.flag = true;
        // or whatever calculation you actually need to do here
        t.into()
    }
}