mysql - 返回引用的生命周期不够长

标签 mysql rust rust-cargo

我刚刚开始学习 Rust,并且主要来自 JavaScript 背景,所以当涉及到整个借用系统和内存管理时,我有点困惑。

我有以下代码:

fn load(db: &MyPool, id: i32) -> &Account{
    let accounts: Vec<Account> = db.prepare("SELECT id, balance, name FROM `accounts` WHERE `id`=?")
    .and_then(|mut stmt| {
        stmt.execute(&[&id]).map(|result| {
            result.map(|x| x.unwrap()).map(|row| {
                Account{
                    id: from_value(&row[0]), 
                    balance: from_value(&row[1]), 
                    name: from_value(&row[2])
                }
            }).collect()
        })
    }).unwrap();

    &accounts[0]

}

而且我已经设法修复了编译器抛出的所有错误 /main.rs:42:4: 42:12 错误:'accounts' 的生命周期不够长

这是从 MySQL 查询中获得一个结果的最佳方式,还是我的做法完全错误?

最佳答案

您不想返回对帐户的引用,但您希望在从数据库中检索后将所有权传递给调用者。

因此,将签名更改为:

fn load(db: &MyPool, id: i32) -> Account

现在的想法是按值而不是按引用返回对象:

accounts[0]

但是这样做会失败并返回 error: cannot move out of indexed content .更好的方法是完全避免在向量中收集,并使用 Iterator::next(&self) 取第一个元素。这看起来像:

fn load(db: &MyPool, id: i32) -> Account{
    let account: Account = db.prepare("SELECT id, balance, name FROM `accounts` WHERE `id`=?")
    .and_then(|mut stmt| {
        stmt.execute(&[&id]).map(|result| {
            result.map(|x| x.unwrap()).map(|row| {
                Account{
                    id: from_value(&row[0]), 
                    balance: from_value(&row[1]), 
                    name: from_value(&row[2])
                }
            }).next().unwrap() // <- next() takes the first elt of the iterator
        })
    }).unwrap();

    account // <- return by value, pass ownership to caller
}

(未经测试,因为我无法重现您的开发环境。)

有点无关,但值得注意的是那些多个 unwrap()调用会使你的函数变得非常脆弱,因为任何失败都会让你的整个程序崩溃。幸运的是,解决这种难闻气味的方法很简单:您想返回 Option<Account>而不是 Account .然后删除对 unwrap() 的所有调用并让 Option<Account>在整个调用过程中传播(您使用 map() 很好,因为它表示“如果找到 None 则返回 None,如果找到 Some(f(a)) 则返回 Some(a)”。)

关于mysql - 返回引用的生命周期不够长,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31356518/

相关文章:

sql - 在 SQL 中选择连续事件集

Mysql - where 子句中的左连接问题

rust - 枚举值的向量会产生所有权问题

rust - 在 crate 的 API 中发布具体类型而不是 `impl trait` 有什么好处?

cmake - 从 CMake 调用 Cargo 的最佳方式?

Rust 集成测试无法 `use` 库

mysql - Varchar类型和性能问题

mysql - 如何从两个字段之一中选择唯一的? (这不等于某个值?)

reference - 构建具有特定生命周期的对象

rust - 运行 cargo run 时带有行号的堆栈跟踪