面试题答案
一键面试fn longer_string(s1: &str, s2: &str) -> &str {
if s1.len() > s2.len() {
s1
} else {
s2
}
}
生命周期处理的必要性
- Rust的借用规则:Rust有严格的借用规则,以确保内存安全。其中一条规则是,引用的生命周期必须小于或等于被引用对象的生命周期。在这个函数中,我们返回的是传入的字符串切片之一,这意味着返回的引用的生命周期必须与传入参数的生命周期相关联。
- 防止悬空引用:如果不处理好生命周期,可能会出现返回的引用指向已释放的内存,即悬空引用。这会导致未定义行为,在运行时可能会引发崩溃或数据损坏。
可能出现的错误情况
- 错误的生命周期标注:如果尝试给函数添加错误的生命周期标注,例如:
fn longer_string<'a, 'b>(s1: &'a str, s2: &'b str) -> &'static str {
if s1.len() > s2.len() {
s1
} else {
s2
}
}
这里错误地标注返回值的生命周期为 'static
,意味着返回的引用会一直存活,而实际上它应该与传入参数的生命周期相关。编译器会报错,指出 s1
或 s2
的生命周期与 'static
不匹配。
2. 生命周期不匹配:如果在调用函数时,传入的字符串切片的生命周期不正确,也会导致错误。例如:
fn main() {
let result;
{
let s1 = "hello";
{
let s2 = "world";
result = longer_string(s1, s2);
}
// 这里s2已经超出作用域,result如果没有正确处理生命周期,
// 就可能指向已释放的内存,编译器会阻止这种情况发生
}
println!("{}", result);
}
在这个例子中,如果 longer_string
函数没有正确处理生命周期,编译器会报错,指出 result
的生命周期可能会超出 s2
的生命周期。