写一个基于sqlx组件的 函数
pub async fn aa<'a, T>(
instance: &'a T,
table_name: &'a str,
select_where: &'a str,
) -> Result<&'a T, MyError>
where
T: Serialize + FromRow<'a, SqliteRow> + WithId + Clone,
{
let conn = database_conn().await?;
let select_sql = generate_select_sql(&table_name, &[], &select_where);
let row = query(&select_sql).fetch_one(&conn).await;
match row {
Ok(row_data) => {
let data = <T as FromRow<'a, SqliteRow>>::from_row(&row_data)?; // 现在 一直报错 row的生命周期
let update_sql =
generate_update_sql(&instance, &table_name, &format!("id={}", &data.id()));
// println!("存在数据:{:?}",a);
println!("update_sql");
}
Err(sqlx::Error::RowNotFound) => {
println!("");
let insert_sql = generate_insert_sql(&instance, &table_name);
let res = execute_sql(vec![insert_sql]).await?;
// 处理没有找到记录的情况
println!("不存在数据")
}
Err(r) => {
println!("错误")
}
};
Ok(instance)
}
报错信息如下:
`row_data` does not live long enough
borrowed value does not live long enoughrustcClick for full compiler diagnostic
sql.rs(161, 9): `row_data` dropped here while still borrowed
sql.rs(155, 12): binding `row_data` declared here
sql.rs(143, 17): lifetime `'a` defined here
sql.rs(156, 24): argument requires that `row_data` is borrowed for `'a`
// size = 32 (0x20), align = 0x8
let row_data: SqliteRow
Go to SqliteRow
没有可用的快速修复
rust 生命周期的问题请教 slqx fromRow的问题
- 写回答
- 好问题 0 提建议
- 追加酬金
- 关注问题
- 邀请回答
-
2条回答 默认 最新
关注 引自免费微信小程序:皆我百晓生
为了解决Rust中生命周期的问题,我们需确保所有借用(borrow)都符合其生命周期约束。在你的函数中,
row_data
的生命周期是基于async
函数内部的执行流,而data
对row_data
的借用则尝试跨越整个函数的生命周期,这是不允许的。解决方法在于调整
FromRow
实现以及如何处理获取的数据行。在 SQLx 中,FromRow
结构体通常被用于将数据库查询结果转换为 Rust 类型。为了确保生命周期正确,我们需要让data
的生命周期与row_data
相同,但同时也要保证data
可以在函数返回时仍然有效。一个可能的解决方案是使用
Box<T>
或者Arc<T>
来延长data
的生命周期,这样data
就不再受限于row_data
的生命周期了。然而,考虑到你希望返回一个引用,这可能不是一个直接的解决方案。另一种方式是返回data
的所有权而非引用,但这可能会改变函数的签名和预期的行为。下面是一个修改后的函数实现示例,其中使用
Box<T>
来管理data
的生命周期,并且函数返回值类型也做了相应的调整:use sqlx::{Pool, Sqlite, Error}; use std::sync::Arc; pub async fn aa<'a, T>( instance: &'a T, table_name: &'a str, select_where: &'a str, ) -> Result<Box<T>, MyError> where T: Serialize + FromRow<SqliteRow> + WithId + Clone + 'static, { let conn = database_conn().await?; let select_sql = generate_select_sql(table_name, &[], select_where); let row_data = query(&select_sql).fetch_one(&conn).await?; let data = Box::new(<T as FromRow<SqliteRow>>::from_row(&row_data)?); let update_sql = generate_update_sql(&*data, table_name, &format!("id={}", data.id())); Ok(data) }
这里的关键变化包括:
- 返回类型从
Result<&'a T, MyError>
改为Result<Box<T>, MyError>
。 - 使用
Box<T>
包装data
,确保data
的生命周期不受限于row_data
。 - 移除了泛型参数
'a
和对'a
的约束,因为现在我们不依赖于任何外部生命周期。 - 在调用
generate_update_sql
之前,使用&*data
来访问data
内部的内容。
这样修改后,
data
的生命周期将不再受限于row_data
,并且函数可以安全地返回data
的所有权。如果你确实需要返回一个引用而不是所有权,你可能需要重新考虑你的设计,或者使用更复杂的内存管理和生命周期管理策略,比如
Rc
、Arc
或者RefCell
等特性,但这通常会增加代码的复杂度和维护难度。在这个场景下,返回所有权是一个更为简洁和安全的选择。解决 无用评论 打赏 举报 编辑记录- 返回类型从
悬赏问题
- ¥15 两台交换机分别是trunk接口和access接口为何无法通信,通信过程是如何?
- ¥15 C语言使用vscode编码错误
- ¥15 用KSV5转成本时,如何不生成那笔中间凭证
- ¥20 ensp怎么配置让PC1和PC2通讯上
- ¥50 有没有适合匹配类似图中的运动规律的图像处理算法
- ¥15 dnat基础问题,本机发出,别人返回的包,不能命中
- ¥15 请各位帮我看看是哪里出了问题
- ¥15 vs2019的js智能提示
- ¥15 关于#开发语言#的问题:FDTD建模问题图中代码没有报错,但是模型却变透明了
- ¥15 uniapp的h5项目写一个抽奖动画