在Rust中如何正确存储Vector以实现跨函数访问共享数据?
实现方案
首先先修正你现有代码的两个小问题:
- main函数定义缺少括号,应该是
fn main() { ... } person::add当前参数类型是String,你传入的字符串字面量是&str类型,调用时需要转换为String
方案1:封装为带状态的存储结构体(更推荐,无额外依赖,符合Rust最佳实践)
这种方案避免了全局可变状态的副作用,更易维护、扩展和测试。
person.rs代码
#[derive(Debug, Clone)] pub struct Person { prefix: String, first_name: String, middle_name: String, last_name: String, } // 定义存储结构体,封装人员集合 #[derive(Debug, Default)] pub struct PersonStore { persons: Vec<Person>, } impl PersonStore { // 新增人员 pub fn add(&mut self, prefix: String, first_name: String, middle_name: String, last_name: String) { let new_person = Person { prefix, first_name, middle_name, last_name, }; println!("New person added: {:?}", new_person); self.persons.push(new_person); } // 列出所有人员 pub fn list(&self) { println!("=== Person List ==="); for (index, person) in self.persons.iter().enumerate() { println!("{}: {:?}", index + 1, person); } } }
main.rs代码
mod person; use person::PersonStore; fn main() { // 初始化存储实例 let mut store = PersonStore::default(); // 调用add方法,注意字符串转String store.add("Mr".to_string(), "Wang".to_string(), "Li".to_string(), "Lou".to_string()); // 调用list方法查看所有数据 store.list(); }
方案2:使用模块级全局存储(适合简单单场景使用)
如果确实需要用模块级的函数直接操作,不需要传递存储实例,可以用全局可变状态,需要用到线程安全的容器,这里用稳定可用的once_cell库实现。
第一步:修改Cargo.toml添加依赖
[dependencies] once_cell = "1.19.0"
第二步:person.rs代码
use once_cell::sync::Lazy; use std::sync::Mutex; #[derive(Debug)] pub struct Person { prefix: String, first_name: String, middle_name: String, last_name: String, } // 定义全局线程安全的Person集合,延迟初始化 static PERSON_STORAGE: Lazy<Mutex<Vec<Person>>> = Lazy::new(|| Mutex::new(Vec::new())); pub fn add(prefix: String, first_name: String, middle_name: String, last_name: String) { let new_person = Person { prefix, first_name, middle_name, last_name, }; println!("New person added: {:?}", new_person); // 获取存储的写锁,插入新数据 PERSON_STORAGE.lock().unwrap().push(new_person); } pub fn list() { println!("=== Person List ==="); // 获取存储的读锁,遍历数据 let persons = PERSON_STORAGE.lock().unwrap(); for (index, person) in persons.iter().enumerate() { println!("{}: {:?}", index + 1, person); } }
第三步:main.rs代码
mod person; fn main() { person::add("Mr".to_string(), "Wang".to_string(), "Li".to_string(), "Lou".to_string()); person::list(); }
注:上述全局方案中的
unwrap为简化错误处理的写法,正式项目中可根据需求对锁中毒的异常场景做适配处理。
内容的提问来源于stack exchange,提问作者RJB
相关产品推荐
相关产品推荐

