Dowen Liu
2021-11-17
第二人示例,我觉得与逃逸闭包无关吧。这个例子反应的应该是 FnMut/FnOnce 语义问题。 把代码改成: fn c_mut2() -> impl for<'a> FnMut(&'a str) -> String { let mut s = "hello ".to_string(); move |i| { s += i; s.clone() } } 这样编译就能通过了。编译器报错是因为 s 作为没有实现 Copy 的变量,不能移出FnMut闭包,如果移出就违反的 FnMut 的要求。 把 impl FnMut 改成 impl FnOnce 也能通过编译。
共 1 条评论
2
?
2021-02-23
应该是唯一的可变应用(独占借用)
2
Geek_2c578d
2022-05-18
第二个示例应该是 move 将所有权移动到闭包后,不能将闭包内捕获的环境变量所有权又移送到外部,否则的话下一次调用 FnMut 时环境变量已经没有了(因为所有权之前移出了),闭包的生命周期长于成员(即环境变量)的生命周期,自然会报错。这也是为什么把FnMut换成FnOnce就能编译通过的原因,因为此时闭包的生命周期和成员(即环境变量)的环境变量相等了
1
Geek_7c4953
2021-05-12
为什么闭包只能是独占借用呢?如果闭包不独占会有什么安全问题?
共 2 条评论
1
张晶鹏
2023-04-28
来自北京
为什么实例2里面 有没有move 一样的呢。正常应该是捕获引用, 如果不加move,即应该是 s 应该是&String类型的啊
万正宇
2022-04-23
--011 /** 1.函数项类型 Fn Item Type 2.函数指针类型 Fn Pointer Type 3.闭包类型 Closure */ /**01*/ struct T(u8, u8); impl T { fn sum(a:u8, b:u8) -> u8 {a+b} fn math(&self) -> u8 { Self::sum(self.0, self.1) } } fn main() { let t = T(1,2); let add = T::sum; let add_math = T::math; assert_eq!(add(1,2), T::sum(1,2)); assert_eq!(add_math(&t), t.math()); } /**02*/ #![allow(unused)] type RGB = (u8, u8, u8); //别名 fn color(c: &str) -> RGB { (255, 255, 255) } fn show(c: fn(&str) -> RGB) { println!("{:?}", color("white")); } fn main() { let white = color; // Fn Item Type let w: fn(&str) -> RGB = white; show(white); //// fn(&str) -> RGB , Fn Pointer Type show(w); //// 隐式转化 println!("{:?}", std::mem::size_of_val(&white)); // 0 ////零大小类型优化 println!("{:?}", std::mem::size_of_val(&w)); // 8 //// Fn, FnMut, FnOnce // let bibao = |s:&str| { (1, 1, 1) }; //定义闭包? show(bibao); } /**03*/ fn counter(i: i32) -> impl FnMut(i32) -> i32 { //i 环境变量,自由变量 move |n| n + i } fn main() { let mut f = counter(2); assert_eq!(3, f(1)); } --012 闭包 /** Ownership , &mut T , &T 所有权,可变借用,不可变借用 FnOnce<()> (to similar = fn(T) 函数指针) , FnMut<()> , Fn<()> call_once(()) , call_mut(()) , call(()) */ fn main() { let mut arr = [1, 2, 3]; let mut c = |i| { //// env_var for idx in 0..3 { arr[idx] = i; } println!("arr = {:?}", arr); }; c(6); } --013 /** 逃逸,非逃逸,实现了的Trait? */ fn c_mut() -> impl for<'a> FnOnce(&'a str) -> String { let mut s = "hello".to_string(); move |i| { s+= i; s } } fn foo<F: Fn() + Copy>(f: F) { f() } fn main() { let i = ", world"; let mut str_closure = c_mut(); let mut arr = [1,2,3]; let p = &mut arr; { let mut c = || { (*p)[0] = 0; }; c(); } let z = &p; //唯一不可变引用 }
展开
陆一鸣猜不动
2022-02-07
没怎么消化,需要回来再看看