FnOne 特征是至少调用一次还是只能调用一次?

26 天前
tedzhou1221  tedzhou1221

在看 B 站上的教程,看到关于 move 和 闭包的东西。 地址是 https://b23.tv/dXol75P

其实中说 FnOne 是至少调用一次。

还有 Rust 圣经中也同样这么说。 内容如下:

所有的闭包都自动实现了 FnOnce 特征,因此任何一个闭包都至少可以被调用一次

但 Kimi 的解释是:

FnOnce 的设计目标是确保闭包在调用时可以安全地消耗变量的所有权,而不是强制要求闭包必须被调用。换句话说:

“只能调用一次”:闭包被设计为只能调用一次,以避免多次调用导致的错误。
“至少调用一次”:这不是 FnOnce 的要求。闭包可以选择不被调用,但一旦调用,就不能再次调用。

大致意思就是“只能调用一次”

我的理解也是只能调用一次。

ps: 前几天看到有个推荐 Rust 教程的页面,说《 Rust 语言圣经》错误太多。我现在找不到出处了。请问有哪些是错误的?

454 次点击
所在节点   Rust  Rust
3 条回复
PTLin
PTLin
25 天前
调用 FnOnce 闭包其实展开是这样
```rust
#![feature(impl_trait_in_bindings)]
#![feature(fn_traits)]
use std::ops::FnOnce;
fn main(){
let a:impl FnOnce()=||{};
a.call_once(());
}
```
call_once(self, args: Args),签名是这样,第一个参数会消耗闭包的所有权,但是有些情况闭包的匿名结构体会被实现 Copy ,这时候即使是 FnOnce 也可以多次被调用。
nebkad
nebkad
24 天前
在实际效果上,FnOnce 最多被调用一次。
在抽象意义上,FnOnce 是 FnMut 和 Fn 的超集,因为 FnMut 和 Fn 总是可以理解为消耗一个 &mut Self 和 &Self 来完成一次调用,而 &mut Self 和 &Self 可以视为 Clone 的(不同的 &mut Self 必然有 lifetime 的区别但也算是可 Clone)
这个逻辑不是那么直观,但还算自洽
geekard
geekard
16 天前
FnOnce 有两个含义:
1. 作为泛型参数的限界,表示该闭包只会被调用一次;
2. 作为传参的闭包函数,它的类型由编译器自动推导,比如 move 捕获的对象时,就只实现了 FnOnce 。

对于第一种作为限界的 FnOnce ,可以传入的闭包类型是最宽松的,也就是可以传入 实现 FnOnce/Fn/FnMut 的闭包。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1107663

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX