哪些具体条件为闭合来实现Fn,FnMut和FnOnce特质?
那是:
FnOnce特性?FnMut特性?Fn特性?例如,改变它的主体上的闭包状态会使编译器无法实现Fn它.
huo*_*uon 104
每个特征代表关于闭包/函数的越来越多的限制性属性,由它们的call_...方法的签名表示,特别是self:
FnOnce(self)是可以调用一次的函数,FnMut(&mut self)是可以在有权&mut访问其环境时调用的函数Fn(&self)是只有在只能&访问其环境时仍可以调用的函数.闭包|...| ...将自动实现尽可能多的闭包.
FnOnce:一个不能被调用的闭包不值得这个名字.请注意,如果只实现闭包FnOnce,则只能调用一次.FnMut,允许多次调用它们(如果对函数对象没有通用的访问).Fn,允许它们在任何地方被调用.这些限制直接self取决于封闭物到结构的类型和"desugaring"(在Rust中查找封闭中描述).
有关Rust中截止日期的闭包的信息,请参阅Rust书中的Closures章节.
鉴于现在只有一个其他答案可能无法让某些人完全清楚问题的内容,因为它对我来说并不完全清楚,我将提供一些示例以及一些推理来帮助我理解这些内容封闭特征都是关于:
\n\xe2\x80\x94 为什么我们需要它们?:“特征是函数和结构如何指定它们可以使用和存储在其中的闭包类型(与结构一样)”
\n\xe2\x80\x94 它们各自对于闭包表示什么:
\nFn:
FnMut:
Fn用于指示的特征。 op 指出:“改变其主体上的闭包状态会使编译器无法Fn在其上实现。”)FnOnce:
(所有这些特征只是编译器确定在何处允许使用任意闭包同时将闭包操作的数据内存保持在“安全”状态的一种方法)
\n\xe2\x80\x94 一些示例:
\n(注意:我无法用“impl”类型注释“updated_vec”let 绑定,因此我将在绑定定义附近的注释中指定 rust 分析器推断的类型)
\nFn特征:fn main() {\n let some_vec = vec![1, 3, 4];\n \n let get_that_same_vec = || { // "get_that_same_vec" type: impl Fn() -> &Vec<i32>\n &some_vec\n // as you can see the closure is specified to implement the *Fn* trait,\n // meaning it can be called however many times since it doesn\'t alter the data it operates on\n // or pass the ownership of that data to any other entity \n };\n // - By using the "&" above we are basically saying that a closure should just return a reference to a value.\n // - If we were to omit the "&" above, we would basically be saying:\n // "return and pass the ownership of this value to whomever decides to invoke this closure"\n // which would basically be like turning it into an infinite generator of that value and its ownership\n // "Oh, another caller wants this value and the ownership of it? Sure, let me take the copy of that value... out of thin air I guess!"\n // As you can figure, Rust doesn\'t allow for that last sentence to be true,\n // since that would allow multiple entities to have the ownership of the underlying memory,\n // which would eventually result in a "double free" error when needing to free that underlying memory when one of the owners goes out of scope. (see: *FnOnce* example) \n\n println!("This is the vec: {:?}", get_that_same_vec());\n println!("This is the vec: {:?}", get_that_same_vec()); // if "&" would not be present above, then this would not compile\n}\nRun Code Online (Sandbox Code Playgroud)\nFnMut:FnMut(关于为什么我们需要用“mut”标记持有闭包的变量,请参阅这个很好的答案)
fn main() {\n let mut some_vec = vec![1, 3, 4];\n\n let mut update_vec = || { // "update_vec" type: impl FnMut()\n some_vec.push(5); \n };\n\n // As you can see the closures that implement the *FnMut* trait can be called multiple times,\n // because they do not pass the ownership of the data they capture out of their scope\n // they only alter its state, and if altering the value of its state multiple times is a legal operation\n // for a type on which the closure operates, then it is surely ok to call such a closure multiple times \n update_vec();\n update_vec();\n println!("This is the updated \\"some_vec\\": {:?}", some_vec);\n // This is the updated "some_vec": [1, 3, 4, 5, 5]\n}\nRun Code Online (Sandbox Code Playgroud)\nFnOnce:(我在这里所做的就是:我删除了示例中闭包内“some_vec”前面的“&” Fn)
fn main() {\n let some_vec = vec![1, 3, 4];\n \n let get_that_same_vec = || { // "get_that_same_vec" type: impl FnOnce() -> Vec<i32>\n some_vec\n // as you can see the closure is specified to implement the *FnOnce* trait,\n // rust-analyzer shows only the most relevant trait that a closure implements\n // meaning that, in this case, a closure is marked as such that can only be called once,\n // since it passes the ownership of the data it captures to another entity.\n // In this case, that entity is the "get_that_same_vec" variable.\n };\n\n println!("This is the vec: {:?}", get_that_same_vec());\n // the call to println below does not compile and throws error "value used here after move",\n // and the way the compiler is able to infer this is by knowing\n // that a closure that implements only the `FnOnce` trait and no other trait\n // can only be called once, it no longer holds the ownership of a value it moved the ownership of the first time it was called.\n println!("This is the vec: {:?}", get_that_same_vec()); // this does not compile\n}\nRun Code Online (Sandbox Code Playgroud)\n