闭合参数:传递一个突变内部变量的函数

发布于 2025-02-03 14:09:04 字数 1740 浏览 1 评论 0 原文

这个想法是要捕获状态(在这种情况下为 x ),将一个函数作为其参数( alterer alterer <,在这种情况下为 canse_x ) /code>),这将决定 内在状态如何变化。

pub fn plus17(h: & u64) -> u64 {
    *h + 17
}

pub fn main() {
    let x = 0; //take x by reference

    let mut change_x = move |alterer: &dyn FnOnce(&u64) ->u64 |  alterer(&x) ;
    change_x(&mut plus17);

    println!("{}", x);
}

但是,我似乎不能正确地理解类型:

error[E0161]: cannot move a value of type dyn for<'r> FnOnce(&'r u64) -> u64: the size of dyn for<'r> FnOnce(&'r u64) -> u64 cannot be statically determined
  --> playground/src/main.rs:19:69
   |
19 |     let mut increment_x = move |alterer: &dyn FnOnce(&u64) ->u64 |  alterer(&x) ;
   |                                                                     ^^^^^^^

error[E0507]: cannot move out of `*alterer` which is behind a shared reference
  --> playground/src/main.rs:19:69
   |
19 |     let mut increment_x = move |alterer: &dyn FnOnce(&u64) ->u64 |  alterer(&x) ;
   |                                                                     ^^^^^^^ move occurs because `*alterer` has type `dyn for<'r> FnOnce(&'r u64) -> u64`, which does not implement the `Copy` trait

我不确定我是否有理由将 dyn 放在哪里,这是编译器的建议,我不确定为什么我为什么必须把它放在那里。是因为 Alterer 尽管输入/返回类型的&amp; amp; u64-&gt; u64 可能是任意大小的?

我还尝试使Alterer成为 fnmut ,而不是 fnonce ,但是我对它们的区别以及给定的更改> Alterer 只能运行一次(在外部闭合 change_x 的调用时)似乎是合理的。

The idea is to to have one closure (change_x in this case) that captures state (x in this case) that takes a function as its parameter(alterer) that would dictate how the inner state changes.

pub fn plus17(h: & u64) -> u64 {
    *h + 17
}

pub fn main() {
    let x = 0; //take x by reference

    let mut change_x = move |alterer: &dyn FnOnce(&u64) ->u64 |  alterer(&x) ;
    change_x(&mut plus17);

    println!("{}", x);
}

I can't seem to get the types right however:

error[E0161]: cannot move a value of type dyn for<'r> FnOnce(&'r u64) -> u64: the size of dyn for<'r> FnOnce(&'r u64) -> u64 cannot be statically determined
  --> playground/src/main.rs:19:69
   |
19 |     let mut increment_x = move |alterer: &dyn FnOnce(&u64) ->u64 |  alterer(&x) ;
   |                                                                     ^^^^^^^

error[E0507]: cannot move out of `*alterer` which is behind a shared reference
  --> playground/src/main.rs:19:69
   |
19 |     let mut increment_x = move |alterer: &dyn FnOnce(&u64) ->u64 |  alterer(&x) ;
   |                                                                     ^^^^^^^ move occurs because `*alterer` has type `dyn for<'r> FnOnce(&'r u64) -> u64`, which does not implement the `Copy` trait

I'm not sure if i'm justified in putting the dyn where i put it, it was a compiler's suggestion and im not really sure why i have to put it there. Is it because the alterer can be of arbitrary size despite the input/return type of &u64->u64?

I have also tried to make alterer a FnMut as opposed to FnOnce, but im also pretty shaky as to their distinction and the fact that a given alterer would run only once (at the moment of invocation by outer closure change_x) seemed reasonable.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

南城追梦 2025-02-10 14:09:04

fnonce 需要一个拥有的 self 。因此, Alterer 不能是 fnonce ,因为它不是拥有的,而是参考。

您可以将其制作&amp; dyn fn &amp; mut dyn fnmut (我建议使用 fnmut ),或进行 box&lt; dyn fnonce&gt;

FnOnce needs an owned self. Thus alterer cannot be FnOnce, because it is not owned but a reference.

You can either make it &dyn Fn or &mut dyn FnMut (I'd recommend going with FnMut), or take Box<dyn FnOnce>.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文