面试题答案
一键面试- 定义
Trait
和结构体:trait Trait { fn do_something(&self, other_data: &i32) -> i32; } struct MyStruct { data: i32, vec: Vec<Box<dyn Trait>>, }
- 实现
Trait
: 为了满足借用规则,我们可以使用Rc
(引用计数)和Weak
(弱引用)。Rc
用于共享数据,Weak
用于避免循环引用。use std::rc::{Rc, Weak}; struct TraitImpl { my_struct_weak: Weak<MyStruct>, } impl Trait for TraitImpl { fn do_something(&self, other_data: &i32) -> i32 { if let Some(my_struct) = self.my_struct_weak.upgrade() { // 这里可以访问`my_struct.data` my_struct.data + *other_data } else { 0 } } }
- 初始化
MyStruct
:impl MyStruct { fn new() -> Self { let my_struct_rc = Rc::new(MyStruct { data: 10, vec: Vec::new(), }); let my_struct_weak = Rc::downgrade(&my_struct_rc); let trait_impl = Box::new(TraitImpl { my_struct_weak }); let mut my_struct = my_struct_rc.into_inner(); my_struct.vec.push(trait_impl); my_struct } }
- 使用示例:
fn main() { let my_struct = MyStruct::new(); let result = my_struct.vec[0].do_something(&20); println!("Result: {}", result); }
在上述代码中:
- 我们定义了一个
Trait
,它有一个方法do_something
,这个方法需要借用MyStruct
中的其他数据。 MyStruct
包含一个data
字段和一个Vec<Box<dyn Trait>>
。TraitImpl
结构体持有一个Weak<MyStruct>
,在do_something
方法中通过upgrade
尝试获取MyStruct
的强引用,如果获取成功则可以访问MyStruct
中的数据。- 在
MyStruct::new
方法中,我们通过Rc
和Weak
来初始化结构体并将实现了Trait
的实例放入vec
中。
这种方式确保了内存安全并且不违反借用规则。