当我可以进行可变变量绑定时,为什么还需要重新绑定/阴影?考虑:
let x = a();
let x = b(x);
Run Code Online (Sandbox Code Playgroud)
与
let mut x = a();
x = b(x);
Run Code Online (Sandbox Code Playgroud)
可变变量绑定允许对此变量进行可变借用.但是,影子比可变绑定有一些优势吗?
我有代码:
struct Foo {}
impl Default for Foo {
fn default() -> Self {
Self {}
}
}
impl Drop for Foo {
fn drop(&mut self) {
// Do something
}
}
fn main() {
{
let foo = Some(Foo::default());
let foo = None; // Would this line trigger `Foo::drop`?
};
{
let mut foo = Some(Foo::default());
foo = None; // Would this line trigger `Foo::drop`?
};
}
Run Code Online (Sandbox Code Playgroud)
s占用的资源是否得到foo正确释放?
第一种情况(变量被覆盖)不会触发drop,所以我添加了第二种情况,我也很困惑。
我偶然发现了以下场景:
fn compute_values(value: &mut String) {
// the first computation should always work:
let computed_value = String::from("computed value");
// override the default String with the computed value:
*value = computed_value;
// some more code that returns a Result with values or an error message
}
fn main() {
let mut value = String::from("default value");
compute_values(&mut value);
println!("value: {value}")
}
Run Code Online (Sandbox Code Playgroud)
这段代码按照我的预期使用 my 进行编译rustc 1.74.1 (a28077b28 2023-12-04)并输出value: computed value,但问题是,该代码是否泄漏内存。
据我了解,*value = computed_value;进入并且它不再可用(rust编译器确认了这一点,我之后不能computed_value。)并且在函数作用域结束时不会取消分配。由于这一行有效地将 a 分配给 …
我目前正在学习Rust编程语言,并且在阅读了有关所有权和生存期概念(我发现它是GC的优雅替代品)之后,我找不到以下问题的答案。就所有权和生存期而言,以下代码按注释说明工作。
fn main() {
let mut x: u32 = 10; // x is pointing to memory in stack
println!("before reassignment: x = {}", x); // prints 10
x = 11; // memory in stack simply has been updated with another value
println!("after reassignment: x = {}", x); // prints 11
} // x is dropped here
Run Code Online (Sandbox Code Playgroud)
每个人都很高兴,但请想象我们是否有这样的代码:
fn main() {
let mut x = Box::new([99; 1000]); // x owns a Box, which owns heap allocated array
println!("before reassignment: x[0] = …Run Code Online (Sandbox Code Playgroud) struct Item {
name: String,
}
impl Item {
fn new(x: &str) -> Item {
Item { name: String::from(x) }
}
fn change_name(&mut self, x: &str) {
self.name = String::from(x);
}
}
fn main() {
let mut item1 = Item::new("Foo");
item1.change_name("Bar");
}
Run Code Online (Sandbox Code Playgroud)
当我调用 时,分配给先前的item1.change_name()会发生什么。什么时候会被叫到?这会泄漏内存吗?String("Foo")namedrop()String("Foo")
根据Rust的书,"当一个绑定超出范围时,它们被绑定的资源被释放".这也适用于阴影吗?
例:
fn foo() {
let v = vec![1, 2, 3];
// ... Some stuff
let v = vec![4, 5, 6]; // Is the above vector freed here?
// ... More stuff
} // Or here?
Run Code Online (Sandbox Code Playgroud) 如果在创建绑定时使用自动类型推导,如何知道绑定的类型?如果右侧的表达式是借位(如let x = &5;),它将是值还是借位呢?如果我重新分配借入或价值会怎样?
仅作支票,如果我使用let mut x: &mut T = &mut T{};或let mut x:&T = & T{};,我可以重新分配借贷,对吗?
Rust 中的零运行时成本混合列表概述了如何在 Rust 中使用元组和正常特征(不是这个问题建议的特征对象)创建异构列表。该列表似乎在很大程度上依赖于阴影,并且每次添加新元素时都会有效地更改列表的整个类型。
这个实现对我来说似乎很棒,但是在查看了一些 Rust 的主页和资源后,我找不到任何明确定义阴影为零成本的地方。据我所知,重复放弃堆栈上的数据比间接的成本低,但重复复制和添加到现有数据而不是改变它听起来很昂贵。
你不用的东西,你不用付钱。更进一步:你所使用的,你不能更好地编写代码。
- 比亚恩·斯特劳斯楚普
阴影似乎满足了第一个要求,但第二个呢?
Rust 的影子实际上是零成本的吗?