面试题答案
一键面试错误原因分析
在Rust中,借用检查器确保在任何给定时间,要么只能有一个可变引用,要么只能有多个不可变引用。在process_data
函数中:
let a = data.value;
这里创建了对data.value
的不可变借用。let b = data.value;
这里又创建了对data.value
的另一个不可变借用。data.value += a + b;
这里尝试对data
进行可变借用以修改value
。此时,data
已经有两个不可变借用(a
和b
),违反了借用规则,所以编译时会出现借用检查错误。
解决方案1:提前计算
struct Data {
value: i32
}
impl Data {
fn new(v: i32) -> Self {
Data { value: v }
}
}
fn process_data(data: &mut Data) -> i32 {
let sum = data.value + data.value;
data.value += sum;
data.value
}
- 对表达式求值过程的影响:直接读取
data.value
两次计算和,然后再进行修改,减少了借用冲突。 - 对程序逻辑的影响:逻辑保持不变,只是求值顺序改变,提前计算了
a + b
的值。
解决方案2:使用临时变量存储value
struct Data {
value: i32
}
impl Data {
fn new(v: i32) -> Self {
Data { value: v }
}
}
fn process_data(data: &mut Data) -> i32 {
let value = data.value;
data.value += value + value;
data.value
}
- 对表达式求值过程的影响:先把
data.value
的值存储到临时变量value
,之后对data
进行可变借用修改value
,避免同时存在不可变和可变借用。 - 对程序逻辑的影响:逻辑上等价于原代码,只是通过临时变量避免了借用冲突。