【问题标题】:Expected a closure that implements the `FnMut` trait, but this closure only implements `FnOnce`期望一个实现“FnMut”特性的闭包,但这个闭包只实现了“FnOnce”
【发布时间】:2021-12-04 01:53:12
【问题描述】:
fn main() {
    let mut x = String::new();
    let y = || {
        let t = x;
    };
    let mut ww = Box::new(y);
    ww();
}

我希望它运行没有任何错误,因为这个实现存在

impl<Args, F, A> FnOnce<Args> for Box<F, A> 

但是我遇到了一些奇怪的错误,我无法理解为什么?

error[E0525]: expected a closure that implements the `FnMut` trait, but this closure only implements `FnOnce`
  --> src/main.rs:22:13
   |
22 |     let y = || {
   |             ^^ this closure implements `FnOnce`, not `FnMut`
23 |         let t = x;
   |                 - closure is `FnOnce` because it moves the variable `x` out of its environment
...
26 |     ww();
   |     ---- the requirement to implement `FnMut` derives from here

error[E0525]: expected a closure that implements the `Fn` trait, but this closure only implements `FnOnce`
  --> src/main.rs:22:13
   |
22 |     let y = || {
   |             ^^ this closure implements `FnOnce`, not `Fn`
23 |         let t = x;
   |                 - closure is `FnOnce` because it moves the variable `x` out of its environment
...
26 |     ww();
   |     ---- the requirement to implement `Fn` derives from here

【问题讨论】:

  • 我不会多次运行它。我只希望它像FnOnce 闭包一样运行一次。这只是我试图更好地理解 Fn* 特征的一个例子。
  • 哼...你是对的。我不知道为什么它没有自动解决。一种解决方法是取消对自己的引用:(*ww)();
  • 嗯。如果你给 ww 一个明确的 FnOnce 类型,它就会编译:let mut ww: Box&lt;dyn FnOnce()&gt; = Box::new(y)
  • @JohnKugelman 不过,这会改变语义,因为现在您正在通过 trait 对象的 vtable 调用闭包。我并不是说 OP 不想要这样 - 特征对象动态分派通常是 原因 为什么要装箱 - 只是指出这不是一回事。 (*ww)() 是调用问题中创建的闭包的方式,但这是一个很好的问题,为什么 ww() 不仅可以工作,就像闭包没有装箱时那样。

标签: rust


【解决方案1】:

[社区工作正在进行中]

解决方案是取消对自己的引用:

(*ww)();

现在为什么编译器会这样做:

Box impl FnOnce 但默认情况下它似乎调用FnMutHow does Boxed closure calls work just like closure calls?

当你这样做时:

let mut ww = Box::new(y);
ww();

假设调用derefDeref 是为box 实现的,但通过借用box 返回&amp;TFnOnce 需要移动盒子。为什么要做 (*ww) 这项工作? ww.deref()ww.deref_mut() 不起作用。真奇怪。 * 可以调用一个神奇的特性吗? https://doc.rust-lang.org/std/ops/trait.CoerceUnsized.html ? https://doc.rust-lang.org/std/ops/trait.DispatchFromDyn.html?

【讨论】:

  • @user4815162342 你说得对
猜你喜欢
  • 1970-01-01
  • 2023-01-14
  • 2022-01-04
  • 2015-07-22
  • 1970-01-01
  • 1970-01-01
  • 2022-09-24
  • 2021-11-21
相关资源
最近更新 更多