面试题答案
一键面试Rust所有权原则主要内容
- 所有权的定义:每个值在Rust中都有一个变量,称为该值的所有者。当所有者离开其作用域时,这个值将被丢弃。
- 唯一性:在任何时刻,一个值只能有一个所有者。这确保了对内存的独占访问,避免数据竞争。
- 借用:可以在不转移所有权的情况下使用值,即借用。借用分为可变借用(
&mut
)和不可变借用(&
)。不可变借用可以有多个,但可变借用同一时间只能有一个,这保证了在修改数据时没有其他引用在使用它。 - 生命周期:每个引用都有一个生命周期,它表示引用保持有效的作用域。生命周期规则确保引用不会指向无效的数据。
防止内存泄漏和悬空指针示例
fn main() {
// 定义一个字符串变量s,s是该字符串的所有者
let s = String::from("hello");
// 将s的所有权转移给s2,此时s不再是所有者,不能再使用s
let s2 = s;
// 这里如果使用s会报错,因为s的所有权已经转移
// println!("{}", s);
// 函数调用,将s2的所有权转移到函数中
take_ownership(s2);
// 这里如果使用s2会报错,因为所有权已经转移到take_ownership函数
// println!("{}", s2);
}
fn take_ownership(some_string: String) {
// some_string在函数结束时离开作用域,字符串占用的内存被释放
println!("{}", some_string);
}
// 借用示例
fn borrow_string(some_string: &String) {
println!("{}", some_string);
}
fn main() {
let s = String::from("world");
// 借用s,不会转移所有权
borrow_string(&s);
// 这里仍然可以使用s,因为所有权没有转移
println!("{}", s);
}
在上述代码中,take_ownership
函数通过获取字符串的所有权,在函数结束时字符串被自动释放,防止了内存泄漏。在借用示例中,borrow_string
函数通过借用字符串,在函数结束后字符串的所有者(s
)仍可正常使用,并且借用规则保证了在借用期间不会出现悬空指针,因为如果在借用期间所有者被释放,编译器会报错。