【问题标题】:rust iterator::any only accepts function which FnMut signature?rust iterator::any 只接受 FnMut 签名的函数?
【发布时间】:2021-11-26 11:13:33
【问题描述】:

https://doc.rust-lang.org/rust-by-example/fn/closures/closure_examples/iter_any.html

Rust 书中提到了 iterator::any 作为闭包的示例,并且 iterator::any 将函数作为带有 FnMut 条件的参数。根据我的理解,FnMut 不应该消耗价值,而只是可变地借用它。仅允许通过 FnOnce 使用。所以我认为下面的代码不会编译,因为 drop(x) 显然消耗了 x,但是它编译了所以我很困惑 drop(x) 是否不消耗值 x 或者函数输入参数可以通过编译器更改。

let array1 = [1, 2, 3];

array1.iter().any(|&x| {
            drop(x);
            return true;
        })

【问题讨论】:

  • 要强制 FnOnce 闭包,您需要按值捕获某些内容并在闭包中使用它,例如like this。将闭包directly 传递给any() 将强制它为FnMut,你会得到一个不同的错误,关于无法在FnMut 闭包中移出捕获。

标签: rust closures


【解决方案1】:

这里有一些误解要解开。

  1. 闭包特征FnMutFnFnOnce 都可以通过引用或值接收它们的参数。闭包类型与参数的传递方式正交。消耗其参数的函数可以被多次调用,并且每次都会消耗其参数。毕竟,每次都是新的争论。 FnOnce 闭包的特殊之处在于调用它会消耗闭包本身

  2. FnMut 闭包在被调用时可以修改自身,也就是说,您至少需要一个可变的闭包借用才能调用它。

  3. 接受FnMut 闭包的函数也将接受任何Fn 闭包,因为所有Fn 闭包都隐含地为FnMut

  4. 你的闭包实际上并没有消耗它的参数。传递给闭包的参数类型为&i32,您使用解构模式来提取i32x。这只有效,因为i32 实现了Copy 特征——您实际上收到了整数的副本,因为它不允许将值移出借位。删除 Copy 的值根本没有任何作用——同样,只有该值的副本传递给 drop(),而 Copy 类型永远无法实现 Drop 特征。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-16
    • 1970-01-01
    • 2022-07-27
    • 1970-01-01
    • 1970-01-01
    • 2011-02-24
    • 2023-03-13
    相关资源
    最近更新 更多