面试题答案
一键面试- 生命周期分析:
- 当函数接受结构体实例作为参数时,参数的生命周期至少要延续到函数调用结束。如果结构体包含字符串引用,要确保这些引用在函数处理期间始终有效。
- 对于返回结果,要注意返回值中涉及的引用不能指向在函数结束时会被销毁的局部变量。
- 代码示例(以Rust语言为例):
// 定义结构体
struct MyStruct<'a> {
s: &'a str,
}
// 定义接受可变数量结构体实例的函数
fn process_structs<'a>(structs: &[MyStruct<'a>]) -> String {
let mut result = String::new();
for s in structs {
result.push_str(s.s);
result.push(' ');
}
result.trim_end().to_string()
}
fn main() {
let s1 = MyStruct { s: "hello" };
let s2 = MyStruct { s: "world" };
let result = process_structs(&[s1, s2]);
println!("{}", result);
}
在上述代码中:
MyStruct
结构体使用了生命周期参数'a
,表明其内部的字符串引用s
的生命周期与传入的生命周期参数'a
相关联。process_structs
函数接受一个&[MyStruct<'a>]
类型的切片,这样保证了传入的结构体实例的生命周期在函数调用期间是有效的。- 函数返回的是一个新的
String
类型,避免了返回可能悬垂的引用。
- 如果是C++语言:
#include <iostream>
#include <vector>
#include <string>
// 定义结构体
struct MyStruct {
const std::string& s;
MyStruct(const std::string& str) : s(str) {}
};
// 定义接受可变数量结构体实例的函数
std::string process_structs(const std::vector<MyStruct>& structs) {
std::string result;
for (const auto& s : structs) {
result += s.s;
result += " ";
}
if (!result.empty()) {
result.pop_back();
}
return result;
}
int main() {
std::string s1 = "hello";
std::string s2 = "world";
MyStruct ms1(s1);
MyStruct ms2(s2);
std::vector<MyStruct> structs = {ms1, ms2};
std::string result = process_structs(structs);
std::cout << result << std::endl;
return 0;
}
在C++代码中:
MyStruct
结构体持有一个const std::string&
类型的字符串引用。process_structs
函数接受const std::vector<MyStruct>&
类型的参数,确保在函数调用期间结构体实例有效。- 函数返回一个新的
std::string
,避免了返回悬垂引用。同时,要注意在C++中使用引用时,要确保引用的对象在使用期间一直存在。在main
函数中,s1
和s2
在创建MyStruct
实例后,生命周期足够长,不会在process_structs
调用期间被销毁。