Rust 当你在锈迹中可变地阴影一个向量时会发生什么?
我目前正在学习rustlings课程,当这个关于移动语义的练习出现时,我感到困惑。其要点如下:Rust 当你在锈迹中可变地阴影一个向量时会发生什么?,rust,move-semantics,ownership,shadowing,Rust,Move Semantics,Ownership,Shadowing,我目前正在学习rustlings课程,当这个关于移动语义的练习出现时,我感到困惑。其要点如下: fn main(){ let vec0 = Vec::new(); let mut vec1 = fill_vec(vec0); //stuff happens } fn fill_vec(vec: Vec<i32>) -> Vec<i32> { let mut vec = vec; //do stuff vec } fn main(){ 设v
fn main(){
let vec0 = Vec::new();
let mut vec1 = fill_vec(vec0);
//stuff happens
}
fn fill_vec(vec: Vec<i32>) -> Vec<i32> {
let mut vec = vec;
//do stuff
vec
}
fn main(){
设vec0=Vec::new();
设mut vec1=fill_vec(vec0);
//事情发生了
}
fn fill_vec(vec:vec)->vec{
设mut-vec=vec;
//做事
vec
}
据我所知,不可变的vec0
被移动到fill_-vec
作为参数vec
,然后被let mut-vec=vec可变地跟踪代码>。由于向量是对堆存储的引用,这是否意味着由于阴影而发生clone()
,还是重复使用同一指针并使其变为可变?为什么在这种情况下会使用阴影
同一个指针是否被重用,只是变了
对。完全相同的对象,在运行时,它本质上是不可操作的
为什么在这种情况下会使用阴影
有些人喜欢通过阴影临时“锁定”和“解锁”绑定的模式,例如
a=…;
…
设mut a=a;
//在适当的地方变异'a'
设a=a;//再次锁定为只读
那真的只是个人喜好。在这里:
- 本可以引入一个新变量,但它真的会更有用吗?它叫什么<代码>向量机
?不像源代码可以重用,它是从中移动的
mut-vec:…
这主要取决于个人选择。从语义上讲,它是同一个对象,只是在你的情况下更改了一个名称 但在当前的实现中,它会将堆栈数据复制到堆栈中的新位置,这样Vec对象的地址就会改变(但堆指针保持不变)。 这样做是因为您可以用新对象隐藏旧名称:
let v = make_first_vec();
let mut v = make_second_vec();
// old v still exists and it would be dropped only at end of block.
更好的示例(您可以运行它):
struct可拖放(i32);
可拖放的impl Drop{
fn下降(&mut自我){
println!(“删除{}”,self.0);
}
}
fn main(){
//同一个物体移动了
//更改堆栈位置但仍为同一对象
//只掉了一次
println!(“相同对象移动开始”);
{
设a=可下降(1);
让old_ref=&a;
println!(“地址是{},&a作为*常量使用);
设mut a=a;
println!(“地址是{},&a作为*常量使用);
设a=a;
println!(“地址是{},&a作为*常量使用);
//无法使用旧引用,因为旧对象已移动
//如果未注释,则编译错误
//println!(“旧对象仍处于活动状态,并且具有{}”,Old_ref.0);
}
println!(“同一对象移动结束”);
//不同对象隐藏
//按相反顺序丢弃
println!(“不同对象隐藏开始”);
{
设a=可下降(2);
让old_ref=&a;
println!(“地址是{},&a作为*常量使用);
设a=可下降(3);
println!(“地址是{},&a作为*常量使用);
println!(“旧对象仍处于活动状态,并且具有{}”,Old_ref.0);
}
println!(“不同对象隐藏结束”);
//不同的对象覆盖
//重写时删除旧对象
println!(“不同对象覆盖开始”);
{
设mut a=可下降(4);
让old_ref=&a;
println!(“地址是{},&a作为*常量使用);
a=可下降(5);
println!(“地址与{}相同,&a与*const_uuu与usize相同);
//无法使用旧引用,因为旧对象已销毁
//如果未注释,则编译错误
//println!(“旧对象仍处于活动状态,并且具有{}”,Old_ref.0);
}
println!(“不同对象覆盖结束”);
}
它打印这个:
Same object moved begin
Address is 140736088967924
Address is 140736088967888
Address is 140736088967892
Dropping 1
Same object moved end
Different object hides begin
Address is 140736088967888
Address is 140736088967892
Old object is still alive and has 2
Dropping 3
Dropping 2
Different object hides end
Different object override begin
Address is 140736088967892
Dropping 4
Address is same 140736088967892
Dropping 5
Different object override end