我有这个函数用于快速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()
中。由于此值将被拥有并返回,因此可以删除row
和client
。甚至插入符号也显示,当我不再需要它时,row
在评估get(0)
后会被丢弃。如果get()
返回将返回值绑定到row
的切片或引用,我会理解,但我认为情况并非如此。为什么它在仅字符串时有效?我该如何解决这个问题? (postgres::types::FromSql<'a>
和'a
生存期是Row.get()
所要求的。
如果
get()
返回将返回值与row
绑定的切片或引用,我会理解,但我认为情况并非如此。
可能是这种情况;从get()
返回的类型必须实现FromSql<'a>
其中'a
是Row
的生存期。但是,返回的值的确切类型是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>
{
...
}
(游乐场)