这是我的代码
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`.
这里有什么问题?
答案 0 :(得分:3)
我认为问题在于:
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])
}