Rust如何创建指向结构体自身all_things的引用型favorite数组
错误原因
你遇到的报错直接来自Option::unwrap()方法的特性:该方法签名为fn unwrap(self) -> T,会直接消费当前Option的所有权,第一次调用my_backpack.all_things.unwrap()后,all_things字段的值就已经被移动,后续访问自然会抛出“值已被移动”的错误。
除此之外你当前的用法本质是构造自引用结构体:同一个结构体的favorite字段引用自身all_things字段内的元素,这种场景下你需要注意赋值完成后不能移动my_backpack、也不能修改all_things(比如重新赋值、修改Vec导致扩容等),否则会触发借用检查报错,避免出现悬垂引用。
正确实现
方案1:不修改原结构体定义
使用Option::as_ref()方法获取all_things的引用,不会消费原字段的所有权,同时满足不拷贝数据、保留字段Option定义的要求:
// 用if let匹配避免None场景下的panic,也可以直接用.as_ref().unwrap() if let Some(all_things) = my_backpack.all_things.as_ref() { my_backpack.favorite = Some([ &all_things[0], &all_things[1], ]); }
方案2:用Rc规避自引用限制(更灵活)
如果你需要在赋值favorite之后仍然可以修改背包物品列表,没有生命周期标注的限制,可以用智能指针Rc包裹元素,仅增加引用计数不会拷贝底层数据:
use std::rc::Rc; struct Things { name: String, } // 不需要生命周期标注 struct Backpack { all_things: Option<Vec<Rc<Things>>>, favorite: Option<[Rc<Things>; 2]>, } // 初始化时用Rc包裹物品 let thing1 = Rc::new(Things { name: String::from("pencil") }); let thing2 = Rc::new(Things { name: String::from("notebook") }); let thing3 = Rc::new(Things { name: String::from("phone") }); let mut my_backpack = Backpack { all_things: None, favorite: None, }; my_backpack.all_things = Some(vec![thing1.clone(), thing2.clone(), thing3.clone()]); // 赋值时clone Rc仅增加计数,无数据拷贝 my_backpack.favorite = Some([thing1, thing2]);
内容的提问来源于stack exchange,提问作者José Luna
相关产品推荐
相关产品推荐

