【问题标题】:Cannot call read on std::net::TcpStream due to unsatisfied trait bounds由于未满足的特征边界,无法在 std::net::TcpStream 上调用读取
【发布时间】:2021-08-04 16:35:02
【问题描述】:

解决方案: 我需要添加“使用 std::io::prelude::*;”到我的代码。我不知道为什么。

我正在尝试从 std::net::TcpStream 读取,但在调用 stream.read(&buf).unwrap 时收到此错误;

结构std::net::TcpStream 存在方法read,但它的 特征界限不满足 方法不能被调用 std::net::TcpStream 由于不满足的特征边界注意: 不满足以下特征界限: std::net::TcpStream: futures::AsyncRead std::net::TcpStream: futures::AsyncReadExt 需要的帮助:来自特质的项目只有在 特征在 scoperustc(E0599) main.rs(31, 16) 中:无法调用方法 由于 tcp.rs(49, 1): 不满足std::net::TcpStream: futures::AsyncReadExt tcp.rs(49, 1): 不满足std::net::TcpStream: futures::AsyncRead mod.rs(580, 8): 该方法可用于 std::boxed::Box<std::net::TcpStream>这里

代码:

use irc::client::prelude::*;
use futures::prelude::*;
use std::net::{IpAddr, Ipv4Addr, SocketAddr, TcpStream};
use std::io;
use futures::{AsyncRead, AsyncReadExt};

const NAME: &str = "nickname";

#[derive(Debug)]
struct DCC {
    ip: IpAddr,
    port: u16,
}

impl DCC {
    fn from_msg(msg: &str) -> Result<DCC, std::num::ParseIntError> {
        let msg_split: Vec<&str> = msg.split_whitespace().collect();
        let ip: u32 = msg_split[3].parse()?;
        let ip_addr: IpAddr = IpAddr::V4(Ipv4Addr::from(ip));
        let port_num: u16 = msg_split[4].parse()?;
        let dcc = DCC{
           ip: ip_addr,
           port: port_num,
        };
        return Ok(dcc);
    }
    async fn connect(&self) -> Result<(), io::Error>{
        let socket_addr = SocketAddr::new(self.ip, self.port);
        let mut socket = TcpStream::connect(socket_addr)?;
        let mut buf = vec![];
        socket.read(&buf).unwrap();
        return Err(io::Error::new(io::ErrorKind::Other, "oh no!"));
    }
}

#[tokio::main]
async fn irc_get(name: &str) -> Result<String, irc::error::Error>{
    let config = Config {
        nickname: Some(NAME.to_owned()),
        server: Some("irc.irchighway.net".to_owned()),
        port: Some(6667),
        use_tls: Some(false),
        channels: vec!["#ebooks".to_owned()],
        ..Config::default()
    };
    let mut client = Client::from_config(config).await?;
    client.identify()?;

    
    let mut stream = client.stream()?;

    //waits for server to log us in and then sends the search request
    loop{ 
        let m = match stream.next().await{
            Some(v) => v,
            None => panic!("at the disco")
        };
        let message = match &m {
                 Ok(message) => match &message.command {Command::NOTICE(_s1, s2)=> {print!("{:?} \n", s2); message}, _ => message},
                Err(_e) => panic!("at the disco")};
        match &message.command{
            Command::NOTICE(_s, msg) => { if msg.contains("Welcome to #ebooks"){break}}, 
            _=> ()    
        }          
    }
    client.send_privmsg("#ebooks", format!["@Search {}", name])?;
    loop{
        let m = match stream.next().await.transpose()?{
            Some(m) => m,
            None => panic!("at the disco")
        };
        match &m.command{
            Command::PRIVMSG(nm, msg) => if nm == NAME {println!("{:?}",m); return Ok(String::from(msg))},
            _ => ()
        }
    }
}


fn main() {
    let dcc = DCC::from_msg(&irc_get(&"romeo and juliet").unwrap()[..]);
    println!("{:?}", dcc);
}

我对 rust 相当陌生,根据文档中的所有示例,我认为我正确使用了 .read。我唯一的想法是,也许是因为我试图在 impl 中编写代码,但我不知道 rust 是否有不同的处理方式。它也因“async fn connect...”和“fn connect...”而失败。

【问题讨论】:

  • 如果没有最小的复制示例,很难知道您在做什么,并且在最东边的整个错误消息*。但是您似乎混合了同步和异步 API,这无济于事。 Rust 中一件非常相关的事情是 trait 方法要求 trait 在范围内read 可能是 Read(如果使用标准库中的同步 tcp 流)或 AsyncRead(通过 AsyncReadExt)上的方法。需要显式导入相应的特征(可能通过“前奏导入”,但在长期情况下我不喜欢这样),以便该方法可以访问。
  • 已编辑问题,包含完整的错误消息和我的所有代码(包括以下答案中建议的新导入语句(未修复错误))。
  • 这也不是我的第一个 rust 项目,我已经用用户登录和 postgressql 构建了一个完整的 Web 应用程序后端。因此,虽然我是新手,但我至少对 rust 很熟悉,到目前为止,我已经阅读了 rustbook 不到一半的内容。

标签: rust


【解决方案1】:

编译器告诉你解决方案:

帮助:只有当 trait 在范围内时,才能使用来自 trait 的项目

您需要导入特征才能使用它们:

use futures::{AsyncRead, AsyncReadExt};

您可能还想使用异步的tokio::TcpStream,而不是std

【讨论】:

  • 我添加了它并没有修复它。我用一条完整的错误消息编辑了我的问题,该消息似乎声称该错误在 TcpStream 本身中。然而,这似乎......不太可能。
  • @aghayes,我补充说你可能需要 tokio one 而不是 std 来实现异步。
猜你喜欢
  • 2022-11-27
  • 1970-01-01
  • 2018-12-29
  • 1970-01-01
  • 1970-01-01
  • 2021-01-17
  • 2021-08-23
  • 1970-01-01
  • 2019-10-11
相关资源
最近更新 更多