Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rust rusqlite MappedRows的返回类型_Rust - Fatal编程技术网

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);
}