首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Rust中将rusqlite连接和语句对象存储在同一个结构中?

如何在Rust中将rusqlite连接和语句对象存储在同一个结构中?
EN

Stack Overflow用户
提问于 2015-08-25 16:33:50
回答 1查看 2.3K关注 0票数 10

我正在编写我的第一个Rust程序,并且与Rust所有权语义相冲突。我已经声明了一个struct,它将封装一个SQLite数据库连接,因此它维护了一个Connection成员。出于性能原因,我还希望保留一个由Statement类型表示的准备语句。下面是我的代码的简化版本:

代码语言:javascript
复制
extern crate rusqlite; // 0.14.0

use rusqlite::{Connection, Statement};

pub struct Foo<'a> {
    conn: Connection,
    statement: Statement<'a>,
}

impl<'a> Foo<'a> {
    pub fn new() -> Foo<'a> {
        let conn = Connection::open(&":memory:").unwrap();
        let statement = conn
            .prepare("INSERT INTO Foo(name, hash) VALUES($1, $2)")
            .unwrap();
        Foo { conn, statement }
    }
}

我试图将conn变量的所有权传递给被调用方,方法是将它存储在Foo的一个成员中,但是当我试图编译这段代码时,它失败了:

代码语言:javascript
复制
error[E0597]: `conn` does not live long enough
  --> src/main.rs:13:25
   |
13 |         let statement = conn
   |                         ^^^^ borrowed value does not live long enough
...
17 |     }
   |     - borrowed value only lives until here
   |
note: borrowed value must be valid for the lifetime 'a as defined on the impl at 10:6...
  --> src/main.rs:10:6
   |
10 | impl<'a> Foo<'a> {
   |      ^^

由于某些原因,rusqlite::Connection类型不接受生存期参数,因此我无法显式地将它的生存期绑定到Statement实例的生存期。

我遗漏了什么?这种封装是一种非常常见的模式,我肯定我遗漏了一些东西。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-08-25 17:26:03

让我们看看Connection::prepare

代码语言:javascript
复制
pub fn prepare<'a>(&'a self, sql: &str) -> Result<Statement<'a>>

如果我们忽略了Result (这意味着这个函数可能失败),这意味着“返回一个不能比调用prepareConnection更长的Statement”。这很可能是因为Statement包含了对Connection的引用。

但是,如果有对项的引用,则无法再移动该项,因为引用将无效。使用无效的引用会导致内存不安全,因此它被阻止了。

基本上,您需要在代码中反映这些对象的生存期和所有权,因此不能将ConnectionStatement捆绑在同一个结构中。相反,其中一个可以引用另一个。

票数 10
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32209391

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档