elasticsearch 需要引用的函数本地所有权

tgabmvqs  于 2022-11-02  发布在  ElasticSearch
关注(0)|答案(1)|浏览(140)

我目前正在尝试使用elasticsearch依赖项构建对ElasticSearch的请求。
下面是我编写的代码的简化版本:

fn test<'a>(client: &'a Elasticsearch) -> BoxFuture<'a, std::result::Result<Bytes, elasticsearch::Error>> {
    let index_parts = ["foo", "bar"]; // Imagine this list being computed and not literal

    let search_response = client
            .search(SearchParts::Index(&index_parts))
            .from(0)
            .size(1000)
            .body(json!(
                { "query": { "match_all": { } } }
            ))
            .send();

    search_response
        .and_then(|resp| resp.bytes())
        .boxed()
}

我得到的错误:
无法返回引用局部变量index_parts的值返回引用当前函数拥有的数据的值
我完全理解为什么会出现这个错误--我在test中创建了一个新数组,但是SearchParts::Index只需要一个&'b [&'b str],所以我没有办法给它 * 赋予 * 所有权,所以我只能这样做。
当然,有几个简单的解决方案,首先,也是最重要的,简单地内联test,而不是创建一个单独的函数,或者以某种方式用Future返回index_parts,但是这些解决方案泄漏了实现细节,我们都知道这是不好的。
那么,如何在不破坏封装的情况下修复此错误呢?

7kqas0il

7kqas0il1#

我的一位同事提出了以下解决方案:

async fn test<'a>(client: &'a Elasticsearch) -> std::result::Result<Bytes, elasticsearch::Error> {
    let index_parts = vec!["foo", "bar"]; // Imagine this list being computed and not literal

    let search_response = client
        .search(SearchParts::Index(&index_parts))
        .from(0)
        .size(1000)
        .body(json!(
            { "query": { "match_all": { } } }
        ))
        .send()
        .await?;

    search_response.bytes().await
}

虽然我知道使用async时,函数体中的所有内容实际上都是闭包,但我觉得应该有一种方法可以在不使用async的情况下实现这一点,但我不确定。
然而,这个解决方案还有一个问题--返回的Future的生存期与Elasticsearch引用的生存期绑定,这会导致后续问题。
要解决此问题,请执行以下操作:

async fn test(client: & Elasticsearch) -> std::result::Result<Bytes, elasticsearch::Error> {
        let client = client.clone();
        async move {
                let index_parts = ["foo", "bar"];

                let search_response = client
                                .search(SearchParts::Index(&index_parts))
                                .from(0)
                                .size(1000)
                                .body(json!(
                                                { "query": { "match_all": { } } }
                                ))
                                .send()
                                .await?;

                Ok(search_response.bytes().await?)
        }.await
}

相关问题