Rust : 闭包、move、复制与移动语义

看看下面,蛮有意思的:

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 = ||{
    v1.push(1);
    println!("no move v1 : {:?}",v1);
    v1
};
let g2 = move||{
    v2.push(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的,外部变量都不存在,灰灰烟灭了;且只能用一次;

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值