借来的价值活得不够久 [英] Borrowed value does not live long enough

查看:37
本文介绍了借来的价值活得不够久的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的代码

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`.

这里有什么问题?

推荐答案

我认为问题出在这里:

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

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

(I've changed the lifetime parameter name to some usual one)

在这里您声明结果中 Rows 参数中的生命周期应该与 Transaction 参数中的生命周期相同(本质上是 Connection 对象).但是,Rows 的生命周期参数等于 Statement 的生命周期,以及 Statement 值(通过调用 prepare() 方法)是一个局部变量,所以它严格小于要求(局部变量的生命周期总是小于参数中指定的生命周期).

Here you are stating that lifetime in Rows parameter in the result should be the same as the lifetime in Transaction parameter (which is essentially a lifetime of Connection object). However, lifetime parameter of Rows equals to the lifetime of a Statement, and Statement value (created by the call of prepare() method) is a local variable, so it is strictly smaller than required (lifetimes of local variables are always smaller than lifetimes specified in parameters).

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

This error is legitimate - Rust prevented an actual logic mistake here. Rows iterator requires a Statement to load its data, but in this case Statement is destroyed while Rows is still alive.

您需要做的是将 Rows 中的数据收集到某个容器(例如 Vec)并返回.但是,insert_user() 似乎是一个不从数据库返回任何内容的查询.对于此类查询,您应该使用 <Statement 上的 code>execute() 方法,你的函数应该是这样的:

What you need to do is to collect the data from Rows to some container (e.g. Vec) and return it. However, insert_user() seems to be a query which does not return anything from the database. For such queries you should use execute() method on Statement, and your function should look like this:

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])
}

这篇关于借来的价值活得不够久的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆