fn main() {
let x = 5;
println!("{}", x);
let x = 3.14;
println!("{}", x);
let x = "Hello";
println!("{}", x);
}发布于 2018-04-22 04:47:24
没什么。
不是的。
不是的。
现在,从代码的角度来看,上述所有内容都应该是正确的。从优化者的角度来看,它们不一定是正确的。例如,优化器可能会注意到第一个和第二个x的使用没有重叠,所以它可以为第二个x重用第一个x的堆栈存储。
也可能不会。据我所知,语言本身对这个问题没有意见。
唯一能保证局部变量释放它的堆栈存储的方法是从它定义的函数返回。
..。好吧,直到你考虑了内衬,这也可能使这不是真的。
短版本:不要担心它,除非您占用了太多的堆栈空间,从而导致了实际的、可测量的问题。
发布于 2018-04-22 04:54:43
可以在隐藏变量之前将该值移出,但最终不能从隐藏变量访问该值。
回答Q1:的决定取决于编译器和数据类型和大小以及OS和系统内存负载(通常基于堆栈的数据类型停留在main的末尾,而基于堆的数据类型如果需要的话可能需要减少)。
回答Q2:跟踪后:No,在隐藏之前: Yes (Value),运行这段代码。
回答Q3:在阴影之后:没有,在隐藏之前:见:处置价值。和生锈手动内存管理
可变范围和阴影:
优势:
一种在隐藏之前仍然访问这些值的方法(注意:移动迫使闭包获得‘x’的所有权):
use std::{thread, time};
fn main() {
let mut v = vec![];
let d = time::Duration::from_millis(100);
let x = 5;
println!("{}", x);
v.push(thread::spawn(move || {
for _ in 1..10 {
thread::sleep(d);
println!("Thread 1: {}", x);
}
}));
let x = 3.14;
println!("{}", x);
v.push(thread::spawn(move || {
for _ in 1..10 {
thread::sleep(d);
println!("Thread 2: {}", x);
}
}));
let x = "Hello";
println!("{}", x);
v.push(thread::spawn(move || {
for _ in 1..10 {
thread::sleep(d);
println!("Thread 3: {}", x);
}
}));
for child in v {
let _ = child.join();
}
}产出:
5
3.14
Hello
Thread 1: 5
Thread 3: Hello
Thread 2: 3.14
Thread 2: 3.14
Thread 3: Hello
Thread 1: 5
Thread 1: 5
Thread 3: Hello
Thread 2: 3.14
Thread 2: 3.14
Thread 3: Hello
Thread 1: 5
Thread 2: 3.14
Thread 3: Hello
Thread 1: 5
Thread 2: 3.14
Thread 1: 5
Thread 3: Hello
Thread 2: 3.14
Thread 1: 5
Thread 3: Hello
Thread 3: Hello
Thread 2: 3.14
Thread 1: 5
Thread 1: 5
Thread 2: 3.14
Thread 3: Hello注意:move强制闭包获得'x‘的所有权,因此本地x的地址与线程x不相同,但值是:
use std::thread;
fn main() {
let mut v = vec![];
let x = 5;
println!("{:p}", &x);
v.push(thread::spawn(move || {
println!("Thread 1: {:p}", &x);
}));
let x = 3.14;
println!("{:p}", &x);
v.push(thread::spawn(move || {
println!("Thread 2: {:p}", &x);
}));
let x = "Hello";
println!("{:p}", &x);
v.push(thread::spawn(move || {
println!("Thread 3: {:p}", &x);
}));
for child in v {
let _ = child.join();
}
}产出:
0x8bf934
0x8bf9b8
0x8bfa40
Thread 1: 0x4a3faec
Thread 2: 0x4c3fae8
Thread 3: 0x4e3fa70发布于 2018-04-22 13:05:07
据我所知,只有一件事需要记住:当值被分配时。
来自书
请注意,隐藏名称不会改变或破坏它绑定到的值,并且该值将继续存在,直到它超出范围,即使它不再以任何方式访问。
之前的值在隐藏后不会更容易访问,并且它将在作用域结束时被销毁,而不是当变量被隐藏时。
如果堆栈上有值,就没什么好担心的:堆栈内存管理完全掌握在处理器手中。
相反,如果该值是堆分配的,则可以将阴影视为临时内存泄漏,该泄漏将在作用域结束时释放。
如果这可能是一个问题,我们可以在隐藏之前使用drop()显式地释放内存:
struct Foo {
_v: Vec<i32>
}
impl Drop for Foo {
fn drop(&mut self) {
println!("dropping foo");
}
}
fn main() {
println!("start");
let x = Foo {_v: vec![1,2,3]};
drop(x);
let x = 100;
println!("end");
}https://stackoverflow.com/questions/49962229
复制相似问题