通用类型的借用值在匹配中的寿命不够长
Generic typed borrowed value does not live long enough in match
我有这个功能可以快速 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)
}
}
目的:连接DB,return不成功则Err();然后执行查询,然后 return Ok(value) 或 Err() 如果出现问题。调用者可以确保获得请求的值或错误原因。最初我有这个与 return 类型 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()
中的 return 值打包到 Ok()
中。由于此值将被拥有并 returned,因此可以删除 row
和 client
。即使是插入符号也显示 row
会在 get(0)
被评估后被删除,当我不再需要它时。如果 get()
会 return 将 return 值绑定到 row
的切片或引用,我会理解,但我认为情况并非如此。为什么它在仅字符串时有效?我怎样才能解决这个问题?
(Row.get()
要求 postgres::types::FromSql<'a>
和 'a
生命周期。)
If get()
would return a slice or reference that ties the return value to row
, I would understand, but I don't think this is the case.
那可以是这样; get()
的返回类型必须实现 FromSql<'a>
,其中 'a
是 Row
的生命周期。但是,返回值的确切类型是 T
.
编译器报错,因为调用者指定的 'a
必须长于行的生命周期。您的代码实际上是说该行必须至少存在 caller-supplied 生命周期,这是不可能的。
解决此问题最直接的方法是说 T
必须在任何可能的生命周期 'a
内实现 FromSql<'a>
,您可以使用 higher-rank trait bound (for
):
fn psql_query<T>(db: &str, query: &str) -> Result<T, postgres::Error>
where T: for <'a> postgres::types::FromSql<'a>
{
...
}
我有这个功能可以快速 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)
}
}
目的:连接DB,return不成功则Err();然后执行查询,然后 return Ok(value) 或 Err() 如果出现问题。调用者可以确保获得请求的值或错误原因。最初我有这个与 return 类型 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()
中的 return 值打包到 Ok()
中。由于此值将被拥有并 returned,因此可以删除 row
和 client
。即使是插入符号也显示 row
会在 get(0)
被评估后被删除,当我不再需要它时。如果 get()
会 return 将 return 值绑定到 row
的切片或引用,我会理解,但我认为情况并非如此。为什么它在仅字符串时有效?我怎样才能解决这个问题?
(Row.get()
要求 postgres::types::FromSql<'a>
和 'a
生命周期。)
If
get()
would return a slice or reference that ties the return value torow
, I would understand, but I don't think this is the case.
那可以是这样; get()
的返回类型必须实现 FromSql<'a>
,其中 'a
是 Row
的生命周期。但是,返回值的确切类型是 T
.
编译器报错,因为调用者指定的 'a
必须长于行的生命周期。您的代码实际上是说该行必须至少存在 caller-supplied 生命周期,这是不可能的。
解决此问题最直接的方法是说 T
必须在任何可能的生命周期 'a
内实现 FromSql<'a>
,您可以使用 higher-rank trait bound (for
):
fn psql_query<T>(db: &str, query: &str) -> Result<T, postgres::Error>
where T: for <'a> postgres::types::FromSql<'a>
{
...
}