我正在寻找关于如何解决Rust 问题的理解.在so,OFC上有很多类似的问题,但没有一个看起来完全相同--所有其他问题似乎都是关于 struct 或‘静态的,我的是关于我从外部库中使用的一个特性,具有开放的生命周期.
我使用tokio_postgres来查询数据库中的行,就像一个人做的那样.我正在努力简化我经常做的一些操作.从查询中获取一组UUID很容易:
pub fn rows_as_first(rows: Vec<Row>) -> Vec<Uuid> {
rows.into_iter().map(|row| row.get(0)).collect()
}
这很管用.但是,当我try 将其泛化时(例如,收集字符串或其他东西):
pub fn rows_as_first_generic<'a, T: FromSql<'a>>(rows: Vec<Row>) -> Vec<T> {
rows.into_iter().map(|row| row.get(0)).collect()
}
我收到一个错误:
error[E0597]: `row` does not live long enough
--> backend-axum/src/queries.rs:64:32
|
63 | pub fn rows_as_first_generic<'a, T: FromSql<'a>>(rows: Vec<Row>) -> Vec<T> {
| -- lifetime `'a` defined here
64 | rows.into_iter().map(|row| row.get(0)).collect()
| --- ^^^-------
| | | |
| | | `row` dropped here while still borrowed
| | borrowed value does not live long enough
| | argument requires that `row` is borrowed for `'a`
| binding `row` declared here
现在,我绝对理解row
只在关闭的时间内存活,这完全有道理.我不明白的是:
-
这个函数的UUID版本有什么不同,它没有抱怨吗?我认为有一些特性使它神奇地工作,我想知道a)它是什么,以及b)当try 在Ruust中重构这样的代码时,将来如何发现这些信息.(这不是我第一次在重构时遇到类似的问题.)
-
如果a)不是引用,因为我拥有它,b)当我根本不想要引用时,我也想拥有最终结果,那么我应该如何为引用添加生存期呢?
我对T: FromSql<'a>
持怀疑态度--也许它需要进一步澄清.get(0)
调用需要它,根据定义,我返回的是来自SQL查询的一些值.但我不想要参考,我想要拥有最终的结果.我很高兴做clone()
米来实现这一点,只是看起来这不是问题所在.(当然,我试着添加了clone()
.)
因此,不知何故,我应该在行上有一个终生说明符,但Tokio_postgres的工作方式是:
client.query(&stmt, params).await?
返回Vec<Row>
,但不包括生存期,因为它是拥有的.所以...我该怎么做?UUID示例是如何工作的?我确信我在这里遗漏了一些基本的和明显的东西,所以...抱歉的.
也谢谢你.