Rust rusqlite MappedRows的返回类型
我正在尝试编写一个返回Rust rusqlite MappedRows的返回类型,rust,Rust,我正在尝试编写一个返回rusqlite::MappedRows的方法: pub fn dump<F>(&self) -> MappedRows<F> where F: FnMut(&Row) -> DateTime<UTC> { let mut stmt = self.conn.prepare("SELECT created_at FROM work ORDER BY created_at ASC")
rusqlite::MappedRows
的方法:
pub fn dump<F>(&self) -> MappedRows<F>
where F: FnMut(&Row) -> DateTime<UTC>
{
let mut stmt =
self.conn.prepare("SELECT created_at FROM work ORDER BY created_at ASC").unwrap();
let c: F = |row: &Row| {
let created_at: DateTime<UTC> = row.get(0);
created_at
};
stmt.query_map(&[], c).unwrap()
}
pub fn dump(&self)->MappedRows
其中F:FnMut(&Row)->DateTime
{
让mut stmt=
self.conn.prepare(“从工作单中选择created_at ASC”).unwrap();
设c:F=|行:&行|{
让您在以下位置创建:DateTime=row.get(0);
创建于
};
stmt.query_映射(&[],c).unwrap()
}
我遇到了一个编译器错误:
错误[E0308]:类型不匹配
-->src/main.rs:70:20
|
70 |设c:F=|行:&行|{
|从这里开始。。。
71 | |让created_位于:DateTime=row.get(0);
72 | |创建于
73 | | };
||u___________________
|
=注意:应为'F'类型`
=注意:已找到类型`[closure@src/main.rs:70:20:73:10]`
我做错了什么
我试图将闭包直接传递给
query\u map
,但我得到了相同的编译器错误。我将把答案分为两部分,第一部分是关于如何在不考虑借用检查器的情况下修复返回类型,第二部分是关于为什么即使修复了返回类型,它也不起作用
§1. 每个闭包都有一个唯一的匿名类型,因此
c
不能是调用者提供的任何类型F
。这意味着这一行永远不会编译:
let c: F = |row: &Row| { ... } // no, wrong, always.
相反,类型应该从dump
函数传播出去,例如:
// ↓ no generics
pub fn dump(&self) -> MappedRows<“type of that c”> {
..
}
无论如何,如果我们使用“impl Trait”,因为MappedRows
被用作迭代器,那么这样说更合适:
#![feature(conservative_impl_trait)]
pub fn dump<'c>(&'c self) -> impl Iterator<Item = Result<DateTime<UTC>>> + 'c {
..
}
// note: wrong, see §2.
§2. 如果你想,比方说,只是想,上面的修正是有效的。但如果返回
rusqlite::MappedRows
,则它不起作用。由于存在生存期问题,编译器将不允许上述操作工作:
或者反转控件,让dump
接受一个函数,该函数dump
将在保持stmt
活动的同时调用,代价是使调用语法变得奇怪:
// ↓~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
pub fn dump<F>(&self, mut f: F) where F: FnMut(Result<DateTime<UTC>>) {
...
for res in stmt.query_map(&[], c).unwrap() {
f(res);
}
}
x.dump(|res| println!("{:?}", res));
这里的问题是,您隐式地试图返回一个闭包,因此要找到解释和示例,您可以搜索它 泛型
的使用意味着调用者决定F
和函数转储的具体类型
您想要实现的目标需要期待已久的功能impl trait
#![feature(conservative_impl_trait)]
pub fn dump<'c>(&'c self) -> impl Iterator<Item = Result<DateTime<UTC>>> + 'c {
..
}
// note: wrong, see §2.
pub fn dump(&self) -> Box<Iterator<Item = Result<DateTime<UTC>>>> {
...
Box::new(stmt.query_map(&[], c).unwrap())
}
// note: wrong, see §2.
error: `stmt` does not live long enough
--> 1.rs:23:9
|
23 | stmt.query_map(&[], c).unwrap()
| ^^^^ does not live long enough
24 | }
| - borrowed value only lives until here
|
note: borrowed value must be valid for the anonymous lifetime #1 defined on the body at 15:80...
--> 1.rs:15:81
|
15 | pub fn dump(conn: &Connection) -> MappedRows<impl FnMut(&Row) -> DateTime<UTC>> {
| ^
// ↓~~~~~~~~~~~~~~~~~~~~~~~~~
pub fn dump(&self) -> Vec<Result<DateTime<UTC>>> {
..
let it = stmt.query_map(&[], c).unwrap();
it.collect()
}
// ↓~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
pub fn dump<F>(&self, mut f: F) where F: FnMut(Result<DateTime<UTC>>) {
...
for res in stmt.query_map(&[], c).unwrap() {
f(res);
}
}
x.dump(|res| println!("{:?}", res));
#![feature(conservative_impl_trait)]
pub fn create_dump_statement(&self) -> Statement {
self.conn.prepare("SELECT '2017-03-01 12:34:56'").unwrap()
}
pub fn dump<'s>(&self, stmt: &'s mut Statement) -> impl Iterator<Item = Result<DateTime<UTC>>> + 's {
stmt.query_map(&[], |row| row.get(0)).unwrap()
}
...
let mut stmt = x.create_dump_statement();
for res in x.dump(&mut stmt) {
println!("{:?}", res);
}