Rust中Iterator::any要求FnMut签名为何可消费传入变量?
问题核心原因
你混淆了Rust闭包Trait约束的作用范围,和闭包入参的使用规则,二者完全是两个独立的逻辑:
- FnOnce/FnMut/Fn的Trait约束,限制的是闭包从外部作用域捕获的变量的使用方式,和闭包自身入参的使用没有任何关系。你哪怕在闭包内部销毁、移动自身入参,都不会影响闭包本身实现哪类Trait。
- 你给出的代码示例中的闭包,根本没有捕获任何外部变量,这类无捕获的闭包默认同时实现FnOnce、FnMut、Fn三个Trait,当然满足
Iterator::any的FnMut约束。
关于drop(x)的合法性解释
你代码里的闭包参数|&x|是模式匹配语法:array1.iter()生成的迭代器产出的是&i32类型的元素,|&x|相当于把传入的引用解引用,由于i32实现了Copy Trait,这里会直接拷贝出一个独立的i32值绑定到x上。drop(x)销毁的只是这个拷贝出来的临时值,既没有修改原数组的内容,也没有消费任何闭包捕获的外部变量,完全合法。
验证反例
如果你真的在闭包中消费捕获的外部非Copy变量,闭包就只会实现FnOnce,传入any时就会触发编译错误,符合你原本对Trait约束的理解:
let array1 = [1, 2, 3]; let s = String::from("test"); // 下面代码编译会报错,因为闭包消费了捕获的外部变量s,只实现FnOnce,不满足FnMut约束 array1.iter().any(|&x| { drop(s); return true; })
内容的提问来源于stack exchange,提问作者pandawithcat
相关产品推荐
相关产品推荐

