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

时间:2017-12-21 22:52:11

标签: rust

我对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在内的所有内容,根据this post实施FnOnce吗?

1 个答案:

答案 0 :(得分: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! }。 要了解原因,请考虑以下事项:

#map {
  margin: 5px;
  position: fixed;
  top: 0;
  width: 45%;
  height: 100vh;
}

#match {
  width: 45%;
  height: auto;
  overflow-y: scroll;
  float: right;
}