Rust闭包返回引用时的规则及与变量本身的关系是什么?-灵析社区

Yourselffff

fn main() { let mut my_string = String::from("Hello, Rust!"); let mut my_s_ref = &mut my_string; let consume_string = || { my_s_ref }; consume_string(); // consume_string(); println!("闭包外部消费字符串: {}", my_string); } fn main() { let my_string = String::from("Hello, Rust!"); let my_s_ref = & my_string; let consume_string = || { // my_s_ref.push_str("string"); my_s_ref }; consume_string(); consume_string(); println!("闭包外部字符串: {}", my_string); } 以上两段代码,一个返回String的可变引用,一个返回不可变引用,为什么返回可变引用的闭包实现了FnOnce,返回不可变引用的闭包只实现了Fn呢? rust返回引用时,遵循什么规则?和my_s_ref本身有关还是my_string有关?

阅读量:194

点赞量:0

问AI
closure 都是 "FnOnce" ,Fn 也是 "FnOnce" 。 可以被多次调用的会是 "FnMut" 。"FnMut" 也是 "FnOnce" 。 可以被多次调用并且不改变“状态”的是 "Fn" 。"Fn" 既是 "FnMut" ,也是 "FnOnce"。 注意 "&String" 可以 "Copy",但是 "&mut String" 不行。所以第一个 "my_s_ref" 被 Move 了,于是不能多次调用。它就只能是 "FnOnce" 。但是后一个里面 "my_s_ref" 可以 "Copy" ,所以可以反复调用。 "closures" (https://link.segmentfault.com/?enc=P8F%2FGDkJ07vxBQItuggGlw%3D%3D.R%2FvHtprkznrkpqBuBxfCPRUCBlWQtOxVywemjPbeb%2BXrL9hdx%2BQqszvCAusPLt%2F0%2B%2FlHfyl64VUQpnNA8sLeIw%3D%3D) «The way a closure captures and handles values from the environment affects which traits the closure implements, and traits are how functions and structs can specify what kinds of closures they can use. Closures will automatically implement one, two, or all three of these "Fn" traits, in an additive fashion, depending on how the closure’s body handles the values:1. "FnOnce" applies to closures that can be called once. All closures implement at least this trait, because all closures can be called. A closure that moves captured values out of its body will only implement "FnOnce" and none of the other "Fn" traits, because it can only be called once. 2. "FnMut" applies to closures that don’t move captured values out of their body, but that might mutate the captured values. These closures can be called more than once. 3. "Fn" applies to closures that don’t move captured values out of their body and that don’t mutate captured values, as well as closures that capture nothing from their environment. These closures can be called more than once without mutating their environment, which is important in cases such as calling a closure multiple times concurrently.»