如何将Vec<String>转换为Rc<Vec<String>>以适配rusqlite的rarray参数要求
问题原因
你遇到的编译错误和Rc<Vec>的转换逻辑无关,错误出在参数传递环节:
你在调用query_map时使用rusqlite::params![vec![values]]的写法,额外给values套了一层Vec,导致实际传入的参数类型是Vec<Rc<Vec<String>>>,和要求的Rc<Vec<Value>>不匹配,自然无法满足ToSql trait约束。
正确修改步骤
- 首先需要提前加载rusqlite的array虚拟表模块,否则运行时会找不到
rarray函数报错 - 你第一种
Rc转换的写法本身没有问题,不需要调整转换逻辑 - 把
params!里多余的vec!去掉,直接传入values即可
修正后完整代码
fn table_data_to_table(ids: &Vec<String>) -> Vec<data::Item> { let db_connection = rusqlite::Connection::open("data.sqlite") .expect("Cannot connect to database."); // 必须加载array模块,否则运行时会找不到rarray函数 rusqlite::vtab::array::load_module(&db_connection) .expect("Failed to load array module"); // 原有Rc转换逻辑是正确的,这里简化了迭代写法效果一致 let values = std::rc::Rc::new(ids.iter().cloned().collect::<Vec<String>>()); let mut statement = db_connection .prepare("select * from item where id in rarray(?);") .expect("Failed to prepare query."); // 去掉多余的vec!包装,直接传values let mut results = statement .query_map(rusqlite::params![values], |row| { Ok(database::ItemData { id: row.get(0)?, name: row.get(1)?, time_tp_prepare: row.get(2)? }) }); match results { Ok(rows) => { let collection: rusqlite::Result<Vec<database::ItemData>> = rows.collect(); match collection { Ok(items) => { // 这里用into_iter替代iter避免多余复制 items.into_iter().map(|item_data| data::Item { id: item_data.id, name: item_data.name, time_to_prepare: item_data.time_tp_prepare }).collect() }, Err(_) => Vec::new(), } }, Err(_) => Vec::new() } }
内容的提问来源于stack exchange,提问作者Dave
相关产品推荐
相关产品推荐

