首页 > 解决方案 > 由于未满足的特征边界,无法在 std::net::TcpStream 上调用读取

问题描述

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

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

该方法read存在于 struct std::net::TcpStream,但其特征边界未满足 由于未满足特征边界而无法调用方法 std::net::TcpStream注意:未满足以下特征边界: 帮助std::net::TcpStream: futures::AsyncRead 要求std::net::TcpStream: futures::AsyncReadExt:仅当特征满足时才能使用特征中的项目在 scoperustc(E0599) main.rs(31, 16) 中:由于未满足的特征边界,无法调用方法std::net::TcpStreamtcp.rs(49, 1):不满足std::net::TcpStream: futures::AsyncReadExt tcp.rs(49, 1):不满足std::net::TcpStream: futures::AsyncReadmod.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 ...”而失败。

标签: rust

解决方案


编译器告诉你解决方案:

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

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

use futures::{AsyncRead, AsyncReadExt};

此外,您可能想要使用tokio::TcpStream哪个是异步的,而不是那个std


推荐阅读