我尝试通过可变引用向函数发送rusqlite
语句,让该函数执行查询并将结果打包到Peekable Iterator中。编译器抱怨我借用的语句的寿命不够长。
如果我删除注解并使用alt,则以下程序可以工作。2代替alt.1。
use std::iter::Peekable;
use rusqlite::{
Error,
MappedRows,
Row,
Statement,
params,
};
fn get_mapped_rows<'stmt>(get_stmt: &'stmt mut Statement<'stmt>,
)-> Peekable<MappedRows<'stmt, impl FnMut(&Row<'_>) -> Result<i64, Error>>> {
get_stmt
.query(params![0, 0])
.unwrap()
.mapped(|row| {
Ok(row.get(0)?)
})
.peekable()
}
fn main() {
let conn = rusqlite::Connection::open("db.sqlite3")
.unwrap();
let mut get_stmt = conn
.prepare("SELECT dbl_time FROM log")
.unwrap();
// Alt. 1
let mut mapped_rows = get_mapped_rows(&mut get_stmt);
/*
// Alt. 2
let mut mapped_rows = get_stmt
.query(params![0, 0])
.unwrap()
.mapped(|row| {
let nbr: i64 = row.get(0)?;
Ok(nbr)
})
.peekable();
*/
while let Some(row_result) = mapped_rows.next() {
match row_result {
Ok(dbl_time) => { println!("dbl_time:{} is_last:{}",
dbl_time,
mapped_rows.peek().is_none()); },
_ => panic!("Error!"),
}
}
}
我希望get_mapped_rows
返回的迭代器在get_stmt
之前被删除,因此我不明白借用的get_stmt
的生存期如何成为问题。
但是编译器说:
error[E0597]: `get_stmt` does not live long enough
--> src/main.rs:31:43
|
26 | let mut get_stmt = conn
| ------------ binding `get_stmt` declared here
...
31 | let mut mapped_rows = get_mapped_rows(&mut get_stmt);
| ^^^^^^^^^^^^^ borrowed value does not live long enough
...
53 | }
| -
| |
| `get_stmt` dropped here while still borrowed
| borrow might be used here, when `get_stmt` is dropped and runs the `Drop` code for type `Statement`
**编辑:**最初我试图将两个不同的语句传入函数:
fn get_rows<'stmt>(
i: u32,
get_stmt_0: &'stmt mut Statement<'_>,
get_stmt_1: &'stmt mut Statement<'_>,
) -> Rows<'stmt> {
let stmt = if i < 42 {
get_stmt_0
} else {
get_stmt_1
};
stmt
.query(params![0, 0])
.unwrap()
}
在这里使用&'stmt mut Statement<'_>
会导致另一个编译器问题:
error: lifetime may not live long enough
--> src/main.rs:13:9
|
9 | get_stmt_0: &'stmt mut Statement<'_>,
| ---------- has type `&mut Statement<'1>`
10 | get_stmt_1: &'stmt mut Statement<'_>,
| ---------- has type `&mut Statement<'2>`
...
13 | get_stmt_0
| ^^^^^^^^^^ assignment requires that `'1` must outlive `'2`
|
= note: requirement occurs because of a mutable reference to `Statement<'_>`
= note: mutable references are invariant over their type parameter
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
error: lifetime may not live long enough
--> src/main.rs:15:9
|
9 | get_stmt_0: &'stmt mut Statement<'_>,
| ---------- has type `&mut Statement<'1>`
10 | get_stmt_1: &'stmt mut Statement<'_>,
| ---------- has type `&mut Statement<'2>`
...
15 | get_stmt_1
| ^^^^^^^^^^ assignment requires that `'2` must outlive `'1`
|
= note: requirement occurs because of a mutable reference to `Statement<'_>`
= note: mutable references are invariant over their type parameter
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
这里我说输入语句和返回值应该共享相同的生命周期。编译器以某种方式指示它们具有不同的类型(分别为不同的生存期'1
和'2
)。那是什么意思?有什么办法解决吗?
编辑2尝试为输入Statements
引入另一个生命周期参数'a
。函数现在看起来像:
fn get_rows<'stmt, 'a>(
i: u32,
get_stmt_0: &'a mut Statement<'_>,
get_stmt_1: &'a mut Statement<'_>,
) -> Rows<'stmt> where 'a: 'stmt
{
let stmt = if i < 42 {
get_stmt_0
} else {
get_stmt_1
};
stmt
.query(params![0, 0])
.unwrap()
}
根据我的理解,我现在声明(使用where
子句)Statements
的生存期必须至少与返回的Rows
的生存期一样长。但我还是得到了和以前一样的错误:
error: lifetime may not live long enough
--> src/main.rs:14:9
|
9 | get_stmt_0: &'a mut Statement<'_>,
| ---------- has type `&mut Statement<'1>`
10 | get_stmt_1: &'a mut Statement<'_>,
| ---------- has type `&mut Statement<'2>`
...
14 | get_stmt_0
| ^^^^^^^^^^ assignment requires that `'1` must outlive `'2`
|
= note: requirement occurs because of a mutable reference to `Statement<'_>`
= note: mutable references are invariant over their type parameter
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
error: lifetime may not live long enough
--> src/main.rs:16:9
|
9 | get_stmt_0: &'a mut Statement<'_>,
| ---------- has type `&mut Statement<'1>`
10 | get_stmt_1: &'a mut Statement<'_>,
| ---------- has type `&mut Statement<'2>`
...
16 | get_stmt_1
| ^^^^^^^^^^ assignment requires that `'2` must outlive `'1`
|
= note: requirement occurs because of a mutable reference to `Statement<'_>`
= note: mutable references are invariant over their type parameter
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
老实说,我不明白这个问题是与生存期有关,还是与在两个不同的输入引用之间进行选择有关。
1条答案
按热度按时间gev0vcfq1#
编译器抱怨
Statement
s* 中的生存期不同,而不是引用的生存期不同。您需要一个单独的生存期来向编译器传达它们是相同的,而不是让它通过使用'_
来推断不同的生存期。这编译: