Option :: map(FnOnce)似乎不接受FnOnce ......?

问题描述 投票:1回答:1

我对Option::map()有点困惑。 documentation说它接受了FnOnce

如果是这样,为什么ab导致汇编错误?

let mut v = 3;

let mut a: &FnOnce(u32) -> u32 = &|x: u32| { v = x; x };
let mut b: &FnMut(u32) -> u32 = &|x: u32| { x };
let mut c: &Fn(u32) -> u32 = &|x: u32| { x };

let o = Option::Some(3);

o.map(a); // trait bound `std::ops::FnOnce(u32) -> u32: std::ops::Fn<(u32,)>` is not satisfied
o.map(b); // trait bound `std::ops::FnMut(u32) -> u32: std::ops::Fn<(u32,)>` is not satisfied
o.map(c); // works

难道不是所有这些,包括ab,根据FnOnce实施this post

rust
1个回答
3
投票

问题是你不是直接用Option::map调用FnOnce,而是使用&FnOnce

但是如果你看看implementors for FnOnce,你会注意到虽然FnOnce是为&Fn实现的,但它没有为&FnOnce&FnMut实现。要了解原因,请考虑以下事项:

let a: &FnOnce(u32) -> u32 = &|x: u32| { v = x; x };
let b: &FnOnce(u32) -> u32 = a;

a(42); // would be allowed if `&FnOnce: FnOnce`, moves `a`
       // actually gives: 
       // error[E0507]: cannot move out of borrowed content
a(6);  // would not be allowed as `a` was moved
b(7);  // would be allowed if `&FnOnce: FnOnce`
       // oh no! this calls the function again!
© www.soinside.com 2019 - 2024. All rights reserved.