泛型类型化借用值在匹配中的生存时间不够长



我有这个函数用于快速SQL查询,那些只期望从数据库中得到一个值。我导入 postgres 0.19.3 库。

fn psql_query<'a, T>(db: &str, query: &str) -> Result<T, postgres::Error>
where
T: postgres::types::FromSql<'a>,
{
let client = Client::connect(&format!("host=localhost user=postgres password={} dbname={}", get_password(), db), NoTls);
match client {
Ok(mut client) => {
match client.query_one(query, &[]) {
Ok(row) => Ok(row.get(0)),
Err(e) => Err(e)
}
}
Err(e) => Err(e)
}
}

目的:连接到数据库,如果不成功,则返回 Err();然后执行查询,如果出现问题,则返回 Ok(value) 或 Err()。调用方可以确保获取请求的值或错误原因。最初我对返回类型Result<String, Error>具有相同的功能,并且它有效!然后我意识到也许我需要从数据库中查询其他数据类型,并考虑使用泛型类型而不是实现单独的函数。当我修改函数以使用泛型类型时,我开始收到以下错误:

error[E0597]: `row` does not live long enough
--> src/hc.rs:108:31
|
100 | fn psql_query<'a, T>(db: &str, query: &str) -> Result<T, postgres::Error>
|               -- lifetime `'a` defined here
...
108 |                 Ok(row) => Ok(row.get(0)),
|                               ^^^^^^^^^^- `row` dropped here while still borrowed
|                               |
|                               borrowed value does not live long enough
|                               argument requires that `row` is borrowed for `'a`

那么......为什么row需要再活下去呢?我的意思是,我只想将get()的返回值打包到Ok()中。由于此值将被拥有并返回,因此可以删除rowclient。甚至插入符号也显示,当我不再需要它时,row在评估get(0)后会被丢弃。如果get()返回将返回值绑定到row的切片或引用,我会理解,但我认为情况并非如此。为什么它在仅字符串时有效?我该如何解决这个问题? (postgres::types::FromSql<'a>'a生存期是Row.get()所要求的。

如果get()返回将返回值与row绑定的切片或引用,我会理解,但我认为情况并非如此。

可能是这种情况;从get()返回的类型必须实现FromSql<'a>其中'aRow的生存期。但是,返回的值的确切类型是T

编译器抱怨,因为调用方指定的'a必须长于行的生存期。 您的代码实际上是在说,该行的生存期必须至少与调用方提供的生存期一样长,这是不可能的。

解决此问题的最直接方法是说T必须为任何可能的生命周期实现FromSql<'a>'a您可以使用更高等级的特征绑定(for):

fn psql_query<T>(db: &str, query: &str) -> Result<T, postgres::Error>
where T: for <'a> postgres::types::FromSql<'a>
{
...
}

(游乐场)

最新更新