不能在 `async` 函数中使用 `form_urlencoded::Serializer`

Cannot use `form_urlencoded::Serializer` in `async` function

我有一个 hyper 服务器设置,或多或少与这里的第三个示例完全相同: https://docs.rs/hyper/0.14.16/hyper/server/index.html 。我的 handle 函数版本调用其他一些 async 函数,并且一切正常,直到我尝试将一些 URL 查询参数编码为其中一个异步函数中的字符串。当我在 handle:

调用的函数之一中包含涉及 Serializer 的四行时,我的项目停止编译
async fn broken_func(&self, param: &str) -> Result<String, Infallible> {
    // ...
    
    let mut s = url::form_urlencoded::Serializer::new(String::new());
    
    // the presence or absence of these two lines has no effect on the bug, but
    // they demonstrate how I'm trying to use the Serializer
    s.append_pair("key", "value");
    println!("{:?}", s.finish());
    
    drop(s); // <-- thought this might help, but it doesn't
    
    // ...
    Ok(query_string)
}

我得到的错误是

generator cannot be sent between threads safely
the trait `std::marker::Sync` is not implemented for `dyn for<'r> std::ops::Fn(&'r str) -> std::borrow::Cow<'_, [u8]>`

我不知道这与 form_urlencoded::Serializer 有什么关系。但是,我知道 Serializer 既是 !Send 又是 !Sync,但在这种情况下,我只在一个函数中使用它,所以我认为这不会有什么不同?如果我删除上面的那四行,它会返回编译。

因此,为了将一些 key/value 对序列化为 URL 查询参数,我必须使用以下内容,这看起来很荒谬——不仅仅是因为这对于某些事情来说不必要地复杂很简单,还因为 url::Url::parse_with_params 在幕后使用了 form_urlencoded::Serializer

let query_string = url::Url::parse_with_params(
        "http://example.com", 
        &[("key", "value")]
    )
    .unwrap()
    .query()
    .map(|s| s.to_owned())
    .unwrap();

知道为什么在 async 函数中显式使用 Serializer 会导致问题吗?

凯撒一针见血。将 s 放在范围内的技巧修复了它。