rust - 由于未满足的特征边界,无法在 std::net::TcpStream 上调用读取
问题描述
解决方案:我需要添加“使用 std::io::prelude::*;” 到我的代码。我不知道为什么。
我正在尝试从 std::net::TcpStream 读取,但在调用 stream.read(&buf).unwrap; 时收到此错误。
该方法
read
存在于 structstd::net::TcpStream
,但其特征边界未满足 由于未满足特征边界而无法调用方法std::net::TcpStream
注意:未满足以下特征边界: 帮助std::net::TcpStream: futures::AsyncRead
要求std::net::TcpStream: futures::AsyncReadExt
:仅当特征满足时才能使用特征中的项目在 scoperustc(E0599) main.rs(31, 16) 中:由于未满足的特征边界,无法调用方法std::net::TcpStream
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 ...”而失败。
解决方案
编译器告诉你解决方案:
help: 只有当 trait 在范围内时,才能使用来自 trait 的项目
您需要导入特征才能使用它们:
use futures::{AsyncRead, AsyncReadExt};
此外,您可能想要使用tokio::TcpStream
哪个是异步的,而不是那个std
。
推荐阅读
- swift - 如何仅使用带有密码的 AES
- python - 如何为同一个ID添加多个信息?
- python - Pandas 解析 json 列并将现有列保存到新数据框中
- javascript - 当用户单击文本时,如何使用 D3.js 切换 svg 文本元素的值?
- apache-camel - ActiveMQ Artemis 任播和组播前缀
- php - 未定义变量:all_data(查看:/var/www/html/resources/views/welcome.blade.php)
- ionic-framework - 如何检测离子4中的滚动方向
- python - 制作两个共享同一轴的 seaborn 计数图
- c# - 泛型扩展方法参数限制
- react-native - 对象返回旧状态