通用类型的借用值在匹配中的寿命不够长

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,因此可以删除 rowclient。即使是插入符号也显示 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>,其中 'aRow 的生命周期。但是,返回值的确切类型是 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>
{
    ...
}

(Playground)