【问题标题】:Borrowed value does not live long enough借来的价值活得不够长
【发布时间】:2015-06-11 14:53:53
【问题描述】:

这是我的代码

extern crate postgres;

use postgres::{Connection, SslMode};

struct User {
    reference: String,
    email: String
}

static DB_URI: &'static str = "postgres://postgres:postgres@localhost/test";

fn main() {

    let conn = Connection::connect(DB_URI, &SslMode::None).unwrap();
    let trans = conn.transaction().unwrap();

    let user = User {
        reference: "123abc".to_string(),
        email: "test@test.com".to_string()
    };

    let result = insert_user(&trans, &user);

    trans.set_commit();
    trans.finish();

}

fn insert_user<'_>(trans: &postgres::Transaction<'_>, user: &User) -> postgres::Result<postgres::rows::Rows<'_>> {
    let query = "INSERT INTO usr (reference, email) VALUES ($1, $2)";
    trans.prepare(query).unwrap().query(&[&user.reference, &user.email])
}

它产生了一个错误:

src/main.rs:31:2: 31:31 error: borrowed value does not live long enough
src/main.rs:31  trans.prepare(query).unwrap().query(&[&user.reference, &user.email])
                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/main.rs:29:114: 32:2 note: reference must be valid for the lifetime '_ as defined on the block at 29:113...
src/main.rs:29 fn insert_user<'_>(trans: &postgres::Transaction<'_>, user: &User) -> postgres::Result<postgres::rows::Rows<'_>> {
src/main.rs:30  let query = "INSERT INTO usr (reference, email) VALUES ($1, $2)";
src/main.rs:31  trans.prepare(query).unwrap().query(&[&user.reference, &user.email])
src/main.rs:32 }
src/main.rs:29:114: 32:2 note: ...but borrowed value is only valid for the block at 29:113
src/main.rs:29 fn insert_user<'_>(trans: &postgres::Transaction<'_>, user: &User) -> postgres::Result<postgres::rows::Rows<'_>> {
src/main.rs:30  let query = "INSERT INTO usr (reference, email) VALUES ($1, $2)";
src/main.rs:31  trans.prepare(query).unwrap().query(&[&user.reference, &user.email])
src/main.rs:32 }
error: aborting due to previous error
Could not compile `test`.

这里有什么问题?

【问题讨论】:

  • 这里有很多问题都有同样的错误。请证明您已完成所需的跑腿工作,并说明这与现有问题有何不同。
  • 我针对这个常见的生锈错误error[E0716]error E0716: temporary value dropped while borrowed (rust) 提出了一个简洁的问题。它链接回这个问题。

标签: rust


【解决方案1】:

我相信问题出在这里:

fn insert_user<'a>(trans: &postgres::Transaction<'a>, user: &User) -> postgres::Result<postgres::rows::Rows<'a>> {

(我已将生命周期参数名称更改为常用名称)

在这里,您要说明结果中Rows 参数中的生命周期应与Transaction 参数中的生命周期相同(本质上是Connection 对象的生命周期)。但是,Rows 的生命周期参数等于 Statement 的生命周期,而 Statement 值(由 prepare() 方法的调用创建)是一个局部变量,因此它严格小于要求的生命周期(本地的生命周期)变量总是小于参数中指定的生命周期)。

这个错误是合法的 - Rust 在这里防止了一个实际的逻辑错误。 Rows 迭代器需要 Statement 来加载其数据,但在这种情况下,Statement 被销毁,而 Rows 仍然存在。

您需要做的是将Rows 中的数据收集到某个容器(例如Vec)并返回。但是,insert_user() 似乎是一个不会从数据库返回任何内容的查询。对于此类查询,您应该在Statement 上使用execute() 方法,并且您的函数应如下所示:

fn insert_user(trans: &postgres::Transaction, user: &User) -> postgres::Result<u64> {
    let query = "INSERT INTO usr (reference, email) VALUES ($1, $2)";
    trans.prepare(query).unwrap().execute(&[&user.reference, &user.email])
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-23
    • 2019-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多