【问题标题】:The method for_each exists but trait bounds not satisfied when using StreamDeckSocket方法 for_each 存在,但使用 StreamDeckSocket 时不满足 trait bounds
【发布时间】:2019-12-23 18:50:12
【问题描述】:

我正在尝试使用 streamdeck-rs 板条箱,但无法让 example code 工作。

我的实现基本上是给出的确切示例:

use futures::future::Future;
use std::env;
use streamdeck_rs::registration::*;
use streamdeck_rs::socket::StreamDeckSocket;

//the fields of these structs doesn't matter
struct GlobalSettings {}
struct ActionSettings {}
struct MessageToSd {}
struct MessageFromSd {}

fn register() {
    let params = RegistrationParams::from_args(env::args()).unwrap();
    let connect =
        StreamDeckSocket::<GlobalSettings, ActionSettings, MessageFromSd, MessageToSd>::connect(
            params.port,
            params.event,
            params.uuid,
        );
    tokio::run(
        connect
            .map_err(|e| println!("connection failed: {:?}", e))
            .and_then(|socket| {
                socket
                    .for_each(|message| println!("recieved: {:?}", message))
                    .map_err(|e| println!("read error: {:?}", e))
            }),
    );
}

我的错误消息会根据我导入的内容而变化,但它始终是“方法for_each 存在但不满足以下特征界限”的变体。对于我现在列出的导入,我的错误消息是:

error[E0599]: no method named `for_each` found for type `streamdeck_rs::socket::StreamDeckSocket<GlobalSettings, ActionSettings, MessageFromSd, MessageToSd>` in the current scope
  --> src/main.rs:37:35
   |
37 |         .and_then(|socket| socket.for_each(|message| println!("recieved: {:?}", message))
   |                                   ^^^^^^^^
   |
   = note: the method `for_each` exists but the following trait bounds were not satisfied:
           `&mut streamdeck_rs::socket::StreamDeckSocket<GlobalSettings, ActionSettings, MessageFromSd, MessageToSd> : std::iter::Iterator`

我可以导入future::Stream

use streamdeck_rs::registration::*;
use streamdeck_rs::socket::StreamDeckSocket;
use std::env;
use futures::future::Future;
use futures::Stream;
//rest same as before

我得到这个错误:

error[E0599]: no method named `for_each` found for type `streamdeck_rs::socket::StreamDeckSocket<GlobalSettings, ActionSettings, MessageFromSd, MessageToSd>` in the current scope
  --> src/main.rs:37:35
   |
37 |         .and_then(|socket| socket.for_each(|message| println!("recieved: {:?}", message))
   |                                   ^^^^^^^^
   |
   = note: the method `for_each` exists but the following trait bounds were not satisfied:
           `&mut streamdeck_rs::socket::StreamDeckSocket<GlobalSettings, ActionSettings, MessageFromSd, MessageToSd> : futures::stream::Stream`
           `&mut streamdeck_rs::socket::StreamDeckSocket<GlobalSettings, ActionSettings, MessageFromSd, MessageToSd> : std::iter::Iterator`
           `streamdeck_rs::socket::StreamDeckSocket<GlobalSettings, ActionSettings, MessageFromSd, MessageToSd> : futures::stream::Stream`



warning: unused import: `futures::Stream`

还要注意有关未使用导入的警告。

因为 StreamDeckSocket 是在 crate 中定义的,所以我无法在其上实现任何特征。

我知道这个问题以几种形式存在,但据我了解,这些答案仅适用于我正在使用的 crate 中缺少 trait 实现的情况。

【问题讨论】:

  • 你肯定想要来自futures::Streamfor_each() 方法,所以你需要把这个特性带入范围。如果这导致更多错误,请将它们添加到问题中,以便我们找出解决方法。
  • @SvenMarnach 添加了有关futures::Stream 错误的更多详细信息
  • 您使用的是什么版本的streamdeck_rsfutures?快速浏览一下文档,StreamDeckSocket 似乎应该实现Stream
  • 另请注意,您的某些结构需要#[derive(Deserialize)]

标签: rust


【解决方案1】:

示例代码 sn-p 不太对,但很接近:

  • 结构需要#[derive(Deserialize, Debug)]
  • 根据the documentation,传递给for_each 的闭包类型错误。

以下编译:

use futures::future::Future;
use futures::stream::Stream;
use serde::Deserialize;
use std::env;
use streamdeck_rs::registration::*;
use streamdeck_rs::socket::StreamDeckSocket;

#[derive(Deserialize, Debug)]
struct GlobalSettings {}

#[derive(Deserialize, Debug)]
struct ActionSettings {}

#[derive(Deserialize, Debug)]
struct MessageToSd {}

#[derive(Deserialize, Debug)]
struct MessageFromSd {}

fn main() {
    let params = RegistrationParams::from_args(env::args()).unwrap();
    let connect =
        StreamDeckSocket::<GlobalSettings, ActionSettings, MessageFromSd, MessageToSd>::connect(
            params.port,
            params.event,
            params.uuid,
        );
    tokio::run(
        connect
            .map_err(|e| println!("connection failed: {:?}", e))
            .and_then(|socket| {
                socket
                    .for_each(|message| {
                        println!("recieved: {:?}", message);
                        Ok(())
                    })
                    .map_err(|e| println!("read error: {:?}", e))
            }),
    );
}

【讨论】:

  • 你能解释一下for_each上的类型吗?是否需要Ok())的实际返回?我仍在尝试学习如何阅读 Rust 类型签名。
  • @Max,当然。基本上,the documentation of for_each 表示它需要一个 FnMut(Self::Item) -&gt; U 类型的闭包,它接受一个参数并返回 U 类型的东西。 UIntoFuture&lt;Item = (), Error = Self::Error&gt; 的简写。 The IntoFuture type 反过来说它要么解析为 Item 类型的值,要么解析为 Error 类型的错误。在这种情况下,Item 就是 ()。因此返回Ok(())
  • 也就是说,这里的 rustc 错误消息相当不透明且难以解析。诊断有改进的空间。幸运的是,rust-lang 项目已经有this issue 来跟踪所述诊断的进度。
猜你喜欢
  • 2021-08-08
  • 2022-11-16
  • 1970-01-01
  • 2017-05-17
  • 2019-08-26
  • 1970-01-01
  • 2021-12-04
  • 2021-01-17
  • 2017-12-13
相关资源
最近更新 更多