看看下面,蛮有意思的:
1 、有move和无move
let b_move = "hello".to_string();//
let c_copy = "hello";//类同 2_u32,复制语义
let d_copy = "world";//类同 2_u32
let e_move = "world".to_string();//移动语义
let b = move||b_move;
let c = move||c_copy;
let d = ||d_copy;
let e = ||e_move;
b();// 移动语义:move转移了所有权;b_move进了闭包内; 同时,外部的b_move不在。
//b();// error
c();//
c();//复制语义:move转移了所有权,c_copy进了闭包内;这是一种所有权转移的储蓄行为;但外部的c_copy还在;
d();
d();//d()还在; d_copy因为复制语义消费掉了,是一种消费行为;外部d_copy还在。
e();//此后,e_move没了,e()没有了 ;=>FnOnce
//e(); //error
//println!("b_move: {:?}",b_move); //error
println!("c_copy: {:?}",c_copy);// 证明c_copy还在
println!("d_copy: {:?}",d_copy);// 证明d_copy还在
//println!("e_move: {:?}",e_move);//error
2、关于println!
println!():是一种特例,这个函数本身并不消费,也不转移。
let m_move = "hello".to_string();
let p_copy = "hello!";
let q_copy = "hello world";//变量为复制语义类型
let z_move = "hello world".to_string();//变量为移动语义类型
let m = || { println!("m_move:{:?}",m_move);} ;
let p = || { println!("p_copy:{:?}",p_copy);};
let q = move|| { println!("q_copy:{:?}",q_copy);};
let z = move || { println!("z_move:{:?}",z_move);};
m();
m();//println!()无影响
p();
p();//p在,p_copy还在,println!()没有影响
q();//q_copy留在q()内部,q_copy外部仍然还在,用的是copy;类似的有u32,i32等
q();
z();
z();//z_move留在z()内部,z_move外部已经不在了;因为移动语义类型
println!("p_copy:{:?}",p_copy);
println!("q_copy:{:?}",q_copy);
println!("m_move:{:?}",m_move);
//println!("z_move:{:?}",z_move);
3、复制语义变量 :变化 与有move、无move
let mut s1 ="world"; //复制语义变量
let mut s2= "world";
let mut f1 = || {
println!("no move: f1 s1 in => {}", s1);
s1 = "hello";
};
let mut f2= move || {
println!(" move: f2 s2 in => {}", s2);
s2 = "hello";
};
f1(); //world
f1(); //hello
f1(); //hello
f2(); //world
f2(); //hello
f2(); //hello
println!("no move s1 : 原来是world,现在是: {} ",s1); //world=>hello
println!(" move s2 : 原来是world,现在是: {} ",s2); //world=>world
总结:对于复制语义类型,有move和无move时,对闭包的影响[结果]是相同的;但是对外部环境的变量是不同的;
无move:外部的变量被改变了; world=>hello
有move:外部环境变量仍没有变化; world=>world
为什么?
4、移动语义:有move、无move
let mut v1:Vec<u32> = vec![];
let mut v2:Vec<u32> = vec![];
let mut v3:Vec<u32> = vec![];
let g1 = ||{
(1);
println!("no move v1 : {:?}",v1);
v1
};
let g2 = move||{
(1);
println!(" move v2 : {:?}",v2);
v2
};
let g3 =move||v3;
g1();
//g1();//error
g2();
//g2();//error
g3();
//g3(); //error
//println!("v1:{:?}",v1);
//println!("v2:{:?}",v2);
//println!("v3:{:?}",v3);
总结:在移动语义的情况下,有无move的,外部变量都不存在,灰灰烟灭了;且只能用一次;