相关疑难解决方法(0)

使用动态数量的.and()创建Diesel.rs查询

在玩Diesel时,我遇到了写一个函数的问题,该函数将Strings 的向量作为输入并执行以下操作:

  1. 将所有Strings 组合到一个大型查询中
  2. 在上运行查询 Connection
  3. 处理结果
  4. 回来一个 Vec

如果我一步构建查询,它可以正常工作:

fn get_books(authors: Vec<String>, connection: SqliteConnection) {
    use schema::ebook::dsl::*;

    let inner = author
        .like(format!("%{}%", authors[0]))
        .and(author.like(format!("%{}%", authors[1])))
        .and(author.like(format!("%{}%", authors[2])));

    ebook
        .filter(inner)
        .load::<Ebook>(&connection)
        .expect("Error loading ebook");
}
Run Code Online (Sandbox Code Playgroud)

如果我尝试以更多步骤生成查询(为了使用输入向量的可变长度需要),我无法编译它:

fn get_books(authors: Vec<String>, connection: SqliteConnection) {
    use schema::ebook::dsl::*;

    let mut inner = author
        .like(format!("%{}%", authors[0]))
        .and(author.like(format!("%{}%", authors[1]))); // <1>

    inner = inner.and(author.like(format!("%{}%", authors[2]))); // <2>

    ebook
        .filter(inner)
        .load::<Ebook>(&connection)
        .expect("Error loading ebook");
}
Run Code Online (Sandbox Code Playgroud)

这会生成以下错误:

inner = inner.and(author.like(format!("%{}%",authors[2])));
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `diesel::expression::operators::Like`, …
Run Code Online (Sandbox Code Playgroud)

rust rust-diesel

6
推荐指数
1
解决办法
1193
查看次数

如何在没有运行时多态性的情况下对迭代器执行 N 次 `flat_map`(或类似操作)?

我希望能够重复一个过程,在这个过程中,我们正在迭代的集合被n多次更改。n仅在运行时已知,并且可由用户指定,因此我们无法将其硬编码到类型中。

通过collect在迭代之间使用中间数据结构的方法是可能的,如下所示:

let n = 10;

let mut vec1 = vec![1, 2, 3];
{
    for _index in 0..n {
        let temp_vec = vec1.into_iter().flat_map(|x| vec![x, x * 2]).collect();
        vec1 = temp_vec;
    }
}
Run Code Online (Sandbox Code Playgroud)

然而,这似乎很浪费,因为我们正在创建中间数据结构,所以我继续寻找直接链接迭代器的解决方案。

起初我认为一个人可以做这样的事情:

let mut iter = vec![1, 2, 3].into_iter();
for index in 0..n {
    iter = iter.flat_map(|x| vec![x, x * 2].into_iter());
}
Run Code Online (Sandbox Code Playgroud)

但是,这不起作用,因为在 Rust 中,迭代器上的所有函数都返回它们自己类型的“复合迭代器”结构。(例如,在 Haskell 中,迭代器上的函数返回适当类型的结果迭代器,它不会变成“越来越大的复合类型”。)将其重写为递归函数也有类似的问题,因为 (a) 我正在返回“某种类型” Iterator' 的类型(接近?)-由于递归而无法手动写出,并且(b)这种类型在基本情况下与递归情况不同。

我发现这个问题是关于有条件地返回一个或另一个迭代器类型,以及impl Iterator用于指示我们返回一些实现 Iterator 特性的具体类型,但我们不关心它的确切性质。与链接答案中的代码类似的示例已在以下代码中实现为maybe_flatmap。这有效。

但是,我不想运行 …

recursion iterator traits rust recursive-type

3
推荐指数
1
解决办法
577
查看次数

有没有办法创建一个异步流生成器来产生重复调用函数的结果?

我想构建一个收集天气更新并将它们表示为流的程序。我想get_weather()在一个无限循环中调用,在finishstart之间有 60 秒的延迟。

简化版本如下所示:

async fn get_weather() -> Weather { /* ... */ }

fn get_weather_stream() -> impl futures::Stream<Item = Weather> {
    loop {
        tokio::timer::delay_for(std::time::Duration::from_secs(60)).await;
        let weather = get_weather().await;
        yield weather; // This is not supported
        // Note: waiting for get_weather() stops the timer and avoids overflows.
    }
}
Run Code Online (Sandbox Code Playgroud)

有没有办法轻松做到这一点?

超过 60 秒tokio::timer::Interval时使用将不起作用get_weather()

fn get_weather_stream() -> impl futures::Stream<Item = Weather> {
    tokio::timer::Interval::new_with_delay(std::time::Duration::from_secs(60))
        .then(|| get_weather())
}
Run Code Online (Sandbox Code Playgroud)

如果发生这种情况,下一个功能将立即启动。我想在上一次get_weather()开始和下一次get_weather()开始之间保持 …

asynchronous rust async-await rust-tokio

3
推荐指数
1
解决办法
1236
查看次数