面试题答案
一键面试Rust所有权机制的三条基本规则
- 每个值都有一个被称为其所有者(owner)的变量:在Rust中,每个数据值都有且仅有一个所有者。例如:
let s = String::from("hello"); // s是字符串"hello"的所有者
这里s
变量拥有String::from("hello")
创建的字符串值的所有权。
2. 值在任一时刻有且只有一个所有者:这意味着同一时间不能有多个变量拥有同一个值的所有权。例如:
let s1 = String::from("world");
let s2 = s1; // s1的所有权转移给了s2,此时s1不再拥有该字符串的所有权,使用s1会报错
// println!("{}", s1); // 这行代码会报错,因为s1已失去所有权
println!("{}", s2);
当执行let s2 = s1;
时,s1
的所有权转移给了s2
,s1
不再能访问这个字符串。
3. 当所有者(变量)离开作用域,这个值将被丢弃:变量的作用域是其在程序中有效的范围。当变量离开作用域时,Rust会自动调用drop
函数来清理该变量所拥有的值占用的资源。例如:
{
let s = String::from("rust"); // s进入作用域
// 在这里可以使用s
} // s离开作用域,Rust自动调用drop函数释放s所拥有的字符串占用的内存
在}
处,s
离开作用域,其所拥有的字符串值被丢弃,内存被释放。
实际代码中遵循这些规则的示例
fn main() {
let num = 5; // num是数字5的所有者
let mut numbers = Vec::new();
numbers.push(num); // num的所有权转移到了numbers向量中,此时num不再有效
// println!("{}", num); // 这行代码会报错,num已失去所有权
let s1 = String::from("hello");
let result = calculate_length(s1); // s1的所有权转移到函数calculate_length中
// println!("{}", s1); // 这里使用s1会报错,因为s1所有权已转移
println!("The length of the string is: {}", result);
}
fn calculate_length(s: String) -> usize {
s.len()
} // s在函数结束时离开作用域,其拥有的字符串被丢弃
在上述代码中,num
变量的所有权转移到numbers
向量,s1
的所有权转移到calculate_length
函数。函数结束时,函数参数 s
离开作用域,其所拥有的字符串被丢弃,整个过程遵循Rust所有权机制的三条基本规则。