trait Trait {
fn do_something(&self);
}
struct ImplementingStruct;
impl Trait for ImplementingStruct {
fn do_something(&self) {
println!("Doing something");
}
}
fn process_vector(vec: Vec<Box<dyn Trait>>) -> Vec<Box<dyn Trait>> {
for item in &vec {
item.do_something();
}
vec
}
所有权变化解释
- 函数调用前:
- 调用者拥有
Vec<Box<dyn Trait>>
类型向量的所有权。这个向量中的每个Box<dyn Trait>
也被调用者所拥有。
- 函数调用时:
- 所有权通过值传递的方式转移到
process_vector
函数中。此时,函数process_vector
拥有Vec<Box<dyn Trait>>
向量的所有权,调用者不再拥有该向量。
- 函数处理过程中:
- 在
for item in &vec
循环中,item
是对向量中Box<dyn Trait>
的不可变借用。这意味着函数可以调用do_something
方法,因为该方法只需要不可变借用self
。由于是借用,Box<dyn Trait>
的所有权仍然属于向量,进而属于process_vector
函数。
- 函数返回后:
process_vector
函数将向量返回,所有权又转移回调用者。调用者再次拥有Vec<Box<dyn Trait>>
向量以及其中每个Box<dyn Trait>
的所有权。这种方式确保了没有内存泄漏(因为所有权总是被明确的所有者持有),也避免了悬空指针(因为所有权转移后原所有者不再能访问相应资源)。