面试题答案
一键面试结构体定义及所有权处理
在Rust中,String
类型拥有它所分配的内存的所有权。当String
离开作用域时,其析构函数会自动释放内存,从而避免内存泄漏。对于包含String
字段的结构体,同样遵循Rust的所有权规则。
// 定义包含字符串字段的结构体
struct MyStruct {
my_string: String,
}
// 使用该结构体的简单函数
fn print_my_struct(s: MyStruct) {
println!("The string is: {}", s.my_string);
}
解释
- 结构体定义:
MyStruct
结构体包含一个my_string
字段,类型为String
。String
是Rust中可增长的、堆分配的字符串类型,它拥有其内部数据的所有权。
- 所有权转移:
- 在
print_my_struct
函数中,参数s
通过值传递,这意味着s
的所有权被转移到了函数内部。函数结束时,s
离开作用域,其my_string
字段所占用的内存会被自动释放,避免了内存泄漏和悬空指针问题。
- 在
- 避免悬空指针:
- Rust的所有权系统在编译时就会检查代码,确保所有指针都是有效的。如果试图在
my_string
已经被释放后访问它,编译器会报错,从而防止悬空指针问题。例如,下面的代码是不合法的:
- Rust的所有权系统在编译时就会检查代码,确保所有指针都是有效的。如果试图在
// 以下代码会导致编译错误
fn main() {
let s1 = MyStruct {
my_string: String::from("hello"),
};
let s2 = s1; // s1的所有权转移给s2
println!("{}", s1.my_string); // 这里访问s1会报错,因为s1已经失去了所有权
}
正确的做法是在let s2 = s1;
之后,使用s2
来访问字符串,如:
fn main() {
let s1 = MyStruct {
my_string: String::from("hello"),
};
let s2 = s1;
println!("{}", s2.my_string);
}
这样可以确保在任何时候都不会出现悬空指针的情况。