【发布时间】: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::AsyncReadstd::net::TcpStream: futures::AsyncReadExt需要的帮助:来自特质的项目只有在 特征在 scoperustc(E0599) main.rs(31, 16) 中:无法调用方法 由于 tcp.rs(49, 1): 不满足std::net::TcpStream: futures::AsyncReadExttcp.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...”而失败。
【问题讨论】:
-
如果没有最小的复制示例,很难知道您在做什么,并且在最东边的整个错误消息*。但是您似乎混合了同步和异步 API,这无济于事。 Rust 中一件非常相关的事情是 trait 方法要求 trait 在范围内。
read可能是Read(如果使用标准库中的同步 tcp 流)或AsyncRead(通过AsyncReadExt)上的方法。需要显式导入相应的特征(可能通过“前奏导入”,但在长期情况下我不喜欢这样),以便该方法可以访问。 -
已编辑问题,包含完整的错误消息和我的所有代码(包括以下答案中建议的新导入语句(未修复错误))。
-
这也不是我的第一个 rust 项目,我已经用用户登录和 postgressql 构建了一个完整的 Web 应用程序后端。因此,虽然我是新手,但我至少对 rust 很熟悉,到目前为止,我已经阅读了 rustbook 不到一半的内容。
标签: rust