如何避免在“循环”中混淆逻辑?

dop*_*umi 4 rust

在这种情况下,尝试尊重 Rust 安全规则导致我编写的代码不如替代方案清晰。

这是边缘,但一定是一种非常常见的模式,所以我想知道是否有更好的方法。

以下示例无法编译

async fn query_all_items() -> Vec<u32> {
    let mut items = vec![];
    let limit = 10;

    loop {
        let response = getResponse().await;

        // response is moved here
        items.extend(response);

        // can't do this, response is moved above
        if response.len() < limit {
            break;
        }
    }

    items
}
Run Code Online (Sandbox Code Playgroud)

为了满足 Rust 安全规则,我们可以预先计算中断条件:

async fn query_all_items() -> Vec<u32> {
    let mut items = vec![];
    let limit = 10;

    loop {
        let response = getResponse().await;

        let should_break = response.len() < limit;

        // response is moved here
        items.extend(response);

        // meh
        if should_break {
            break;
        }
    }

    items
}
Run Code Online (Sandbox Code Playgroud)

还有其他办法吗?

Rob*_*ier 5

I agree with Daniel's point that this should be a while rather than a loop, though I'd move the logic to the while rather than creating a boolean:

let mut len = limit;
while len >= limit {
    let response = queryItems(limit).await?;

    len = response.len();

    items.extend(response);
}
Run Code Online (Sandbox Code Playgroud)