面试题答案
一键面试在Rust中,每个值都有一个唯一的所有者,当一个变量被赋值给另一个变量时,会发生所有权的转移,这一过程遵循move语义。
-
基本原理
- 当使用
=
将一个变量赋值给另一个变量时,如果被赋值的变量所指向的值是不可复制类型(例如String
,Vec
等),Rust会把该值的所有权从源变量转移到目标变量。这意味着源变量不再拥有该值,不能再合法地使用它。 - 这是Rust内存安全机制的核心部分,它确保在任何时刻,内存中的数据只有一个所有者,从而避免了诸如悬空指针或重复释放内存等问题。
- 当使用
-
举例说明
fn main() {
let s1 = String::from("hello");
let s2 = s1; // 这里发生了move语义,s1的所有权转移给了s2
// println!("{}", s1); // 这一行会报错,因为s1不再拥有该字符串的所有权
println!("{}", s2);
}
在上述代码中,s1
创建了一个String
类型的字符串。当执行let s2 = s1;
时,s1
的所有权被转移到了s2
,s1
不再有效。如果尝试在let s2 = s1;
之后使用s1
,编译器会报错,提示s1
已经被移动。
再看一个涉及函数调用的例子:
fn takes_ownership(s: String) {
println!("{}", s);
}
fn main() {
let s = String::from("world");
takes_ownership(s); // s的所有权转移到了takes_ownership函数中
// println!("{}", s); // 这里会报错,因为s的所有权已经转移
}
在这个例子中,s
作为参数传递给takes_ownership
函数,s
的所有权被转移到函数内部。函数结束时,函数内部的String
对象被释放。同样,在函数调用之后再尝试使用s
会导致编译错误,因为s
的所有权已经不在当前作用域。