use std::net::TcpListener;
use std::io::{Read,Write};
fn main(){
let listener = TcpListener::bind("127.0.0.1:4000").unwrap();
println!("Running on port 4000....");
// let result = listener.accept().unwrap();
for stream in listener.incoming(){
let mut stream = stream.unwrap();
println!("connection established");
let mut buffer = [0; 1024];
stream.read(&mut buffer).unwrap();
}
}
为什么非要use std::io::{Read,Write};
显式地引入Trait呢?impl trait Read的代码不是在TcpListener里已经有了吗?
1
共 7 条评论, 1 页
评论区
写评论尖括号里的被吃了
👇
xiaopengli89: 如果 2 个 Trait 有相同的方法,一个 struct 同时实现了这 2 个 Trait,你不显示 use 进来,编译器怎么知道你要调用哪个? PS:如果 2 个都需要引入的情况,需要用 ::method(t, ..) 来调用(UFCS)
如果 2 个 Trait 有相同的方法,一个 struct 同时实现了这 2 个 Trait,你不显示 use 进来,编译器怎么知道你要调用哪个? PS:如果 2 个都需要引入的情况,需要用 ::method(t, ..) 来调用(UFCS)
初学rust的时候确实容易迷惑,看起来明明是成员方法,但却需要额外引入,或者看起来明明没有引入的方法,却能直接使用。
前者就是楼主这种情况,就是tcpstream的代码页面没有直接实现读写方法的trait而已,比如说读只是定义了
impl Read for TcpStream
,然后需要你自己引入trait Read
,标准库虽然提供了读写trait但也需要额外引入,理论上可以自己重写或引入第三方库。其实这种额外引入在rust也不是太常见,大多数人的编码习惯还是数据和方法绑定引入。遇到这种情况只能多翻翻文档,看看example或test,也没有说次次遇到这种情况就能一眼明了的。
当年看 TRPL 的猜数字时也不理解
use rand::Rng
是干啥的。需要如此手动引入,Rust 在查找方法时才会考虑这个 trait,让编译器自动考虑所有可能的 trait 似乎不太现实。
因为TcpStream本身并没有实现read的功能,所以你要告诉编译器哪里能找到具体实现该功能的相关代码。看一看说明文档就能看见std::io提供合适的方法,你照样可以去写自己的read方法或引入别的库里的read。
显示声明
先看完你手边的学习资料,一般后面都会写为什么。