简体   繁体   English

StreamExt.scan() 方法上的“预期绑定生命周期参数,找到具体生命周期”

[英]“expected bound lifetime parameter, found concrete lifetime” on StreamExt .scan() method

I am using async-tungstenite to listen to a websocket, and async-std's StreamExt to operate on the resulting stream.我正在使用 async-tungstenite 监听 websocket,并使用 async-std 的 StreamExt 对生成的 stream 进行操作。

I want to use a HashMap to accumulate the latest Ticker values from the websocket.我想使用 HashMap 从 websocket 中累积最新的 Ticker 值。 These Ticker values will be looked up later to be used in calculations.稍后将查找这些 Ticker 值以用于计算。 I'm using the symbol (String) value of the Ticker struct as the key for the HashMap.我使用 Ticker 结构的符号(字符串)值作为 HashMap 的键。 I'm using the.scan StreamExt method to perform the accumulation.我正在使用 .scan StreamExt 方法来执行累积。

However, I get a compilation error related to lifetimes.但是,我收到与生命周期相关的编译错误。 Here's some stripped-down code:这是一些精简的代码:

        let tickers = HashMap::new();
        let mut stream = ws.
            .scan(tickers, accumulate_tickers);
        while let msg = stream.next().await {
            println!("{:?}", msg)
        }

...and the accumulate_tickers function: ...以及累积的代码 function:

fn accumulate_tickers(tps: &mut HashMap<String, Ticker>, bt: Ticker) -> Option<&HashMap<String, Ticker>> {
    tps.insert((*bt.symbol).to_string(), bt);
    Some(tps)
}

The compilation error I receive is as follows:我收到的编译错误如下:

error[E0271]: type mismatch resolving `for<'r> <for<'s> fn(&'s mut std::collections::HashMap<std::string::String, ws_async::model::websocket::Ticker>, ws_async::model::websocket::Ticker) -> std::option::Option<&'s std::collections::HashMap<std::string::String, ws_async::model::websocket::Ticker>> {accumulate_tickers} as std::ops::FnOnce<(&'r mut std::collections::HashMap<std::string::String, ws_async::model::websocket::Ticker>, ws_async::model::websocket::Ticker)>>::Output == std::option::Option<_>`
--> examples/async_std-ws.rs:64:4
   |
64 |         .scan(tickers, accumulate_tickers);
   |          ^^^^ expected bound lifetime parameter, found concrete lifetime

I'm unaware of a way to provide a lifetime parameter to the scan method.我不知道有一种方法可以为扫描方法提供生命周期参数。

I wonder whether the issue may be related to the fact that I modify the HashMap and then try to return it (is it a move issue?).我想知道这个问题是否可能与我修改了 HashMap 然后尝试退货有关(是移动问题吗?)。 How could I resolve this, or at least narrow down the cause?我该如何解决这个问题,或者至少缩小原因?

I was able to get this working.我能够得到这个工作。 Working my way through the compiler errors, I ended up with this signature for the accumulate_tickers function:通过编译器错误,我最终得到了accumulate_tickers function 的签名:

fn accumulate_tickers<'a>(tps: &'a mut &'static HashMap<String, Ticker>, bt: Ticker) -> Option<&'static HashMap<String, Ticker>>

I do want the accumulator HashMap to have a static lifetime so that makes sense.我确实希望累加器 HashMap 具有 static 寿命,所以这是有道理的。 tps: &'a mut &'static HashMap... does look a bit strange, but it works. tps: &'a mut &'static HashMap...确实看起来有点奇怪,但它确实有效。

Then, this issue was was that tickers also had to have a static lifetime (it's the initial value for the accumulator. I tried declaring it as static outside the main but it wouldn't let me set it to the result of a function - HashMap::new() . Then, this issue was was that tickers also had to have a static lifetime (it's the initial value for the accumulator. I tried declaring it as static outside the main but it wouldn't let me set it to the result of a function - HashMap::new()

I then turned to lazy_static which allows me to create a static value which does just that:然后我转向lazy_static ,它允许我创建一个static值,它就是这样做的:

lazy_static! {
    static ref tickers: HashMap<String, Ticker> = HashMap::new();
}

This gave me a HashMap accumulator that had a static lifetime.这给了我一个具有 static 寿命的 HashMap 累加器。 However, like normal static values declared in the root scope, it was immutable.然而,就像在根 scope 中声明的正常 static 值一样,它是不可变的。 To fix that, I read some hints from the lazy_static team and then found https://pastebin.com/YES8dsHH .为了解决这个问题,我阅读了lazy_static 团队的一些提示,然后找到了 https://pastebin.com/YES8dsHH This showed me how to make my static accumulator mutable by wrapping it in Arc<Mutex<_>> .这向我展示了如何通过将 static 累加器包装在Arc<Mutex<_>>中来使其可变。

lazy_static! {
    // from https://pastebin.com/YES8dsHH
    static ref tickers: Arc<Mutex<HashMap<String, Ticker>>> = {
        let mut ts = HashMap::new();
        Arc::new(Mutex::new(ts))
    };
}

This does mean that I have to retrieve the accumulator from the Mutex (and lock it) before reading or modifying it but, again, it works.这确实意味着我必须在读取或修改它之前从 Mutex 中检索累加器(并锁定它),但它再次起作用。

Putting it all together, the stripped-down code now looks like this:把它们放在一起,精简后的代码现在看起来像这样:

#[macro_use]
extern crate lazy_static;

lazy_static! {
    // from https://pastebin.com/YES8dsHH
    static ref tickers: Arc<Mutex<HashMap<String, Ticker>>> = {
        let mut ts = HashMap::new();
        Arc::new(Mutex::new(ts))
    };
}

// SNIP

    // Inside main()
    let mut ticks = ws
        .scan(&tickers, accumulate_tickers);
    while let Some(msg) = ticks.next().await {
        println!("{:?}", msg.lock().unwrap());
    }

// SNIP

fn accumulate_tickers<'a>(tps: &'a mut &'static tickers, bt: Ticker) -> Option<&'static tickers> {
    tps.lock().unwrap().insert((*bt.symbol).to_string(), bt);
    Some(tps)
}

I'd be happy to hear suggestions for ways in which this could be made simpler or more elegant.我很高兴听到有关如何使这变得更简单或更优雅的建议。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 预期的约束寿命参数,找到具体的寿命 - Expected bound lifetime parameter, found concrete lifetime 预期的约束寿命参数,找到的混凝土寿命[E0271] - Expected bound lifetime parameter, found concrete lifetime [E0271] 如何解决:预期的混凝土寿命,但找到了约束寿命参数 - How to fix: expected concrete lifetime, but found bound lifetime parameter 锈蚀寿命误差预期具体寿命但发现约束寿命 - Rust lifetime error expected concrete lifetime but found bound lifetime 预期的混凝土寿命,在结构中存储fn时找到约束寿命参数 - Expected concrete lifetime, found bound lifetime parameter when storing a fn in a struct 函数引用:预期的约束生命周期参数,找到具体的生命周期[E0271] - Function references: expected bound lifetime parameter , found concrete lifetime [E0271] 预期绑定生命周期参数,在尝试传递选项时找到具体生命周期<fnonce></fnonce> - Expected bound lifetime parameter, found concrete lifetime when trying to pass an Option<FnOnce> 当使用参数的生命周期作为特征参数时,“预期的关联类型,找到`u32`” - “Expected associated type, found `u32`” when using the lifetime of a parameter as trait parameter in where bound 从闭包填充集合时,键入不匹配“绑定生命周期参数”与“具体生命周期” - Type mismatch “bound lifetime parameter” vs “concrete lifetime” when filling a collection from a closure 尝试调用泛型函数时出现“预期的绑定生命周期参数”错误 - “expected bound lifetime parameter” error when attempting to call a generic function
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM