FnOne 特征是至少调用一次还是只能调用一次? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
tedzhou1221
V2EX    Rust

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

  •  
  •   tedzhou1221 261 天前 1473 次点击
    这是一个创建于 261 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

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

    但 Kimi 的解释是:

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

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

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

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

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

    PTLin
        1
    PTLin  
       260 天前
    调用 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
        2
    nebkad  
       259 天前
    在实际效果上,FnOnce 最多被调用一次。
    在抽象意义上,FnOnce 是 FnMut 和 Fn 的超集,因为 FnMut 和 Fn 总是可以理解为消耗一个 &mut Self 和 &Self 来完成一次调用,而 &mut Self 和 &Self 可以视为 Clone 的(不同的 &mut Self 必然有 lifetime 的区别但也算是可 Clone)
    这个逻辑不是那么直观,但还算自洽
    geekard
        3
    geekard  
       251 天前
    FnOnce 有两个含义:
    1. 作为泛型参数的限界,表示该闭包只会被调用一次;
    2. 作为传参的闭包函数,它的类型由编译器自动推导,比如 move 捕获的对象时,就只实现了 FnOnce 。

    对于第一种作为限界的 FnOnce ,可以传入的闭包类型是最宽松的,也就是可以传入 实现 FnOnce/Fn/FnMut 的闭包。
    Observer42
        4
    Observer42  
       199 天前
    这段《 Rust 语言圣经》也没说错,“至少可以被调用一次”
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     4374 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 01:01 PVG 09:01 LAX 18:01 JFK 21:01
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86