我正在编写一个简单的TCP聊天引擎来学习Rust。
use std::io::{TcpListener, TcpStream};
use std::io::{Acceptor, Listener};
enum StreamOrSlice {
Strm(TcpStream),
Slc(uint, [u8, ..1024])
}
fn main() {
let listener = TcpListener::bind("127.0.0.1", 5555);
// bind the listener to the specified address
let mut acceptor = listener.listen();
let (tx, rx) = channel();
spawn(proc() {
let mut streams: Vec<TcpStream> = Vec::new();
match rx.recv() {
Strm(mut stream) => {
streams.push(stream);
}
Slc(len, buf) => {
for stream in streams.iter() {
stream.write(buf.slice(0, len));
}
}
}
});
// accept connections and process them, spawning a new tasks for each one
for stream in acceptor.incoming() {
match stream {
Err(e) => { /* connection failed */ }
Ok(mut stream) => {
// connection succeeded
tx.send(Strm(stream.clone()));
let tx2 = tx.clone();
spawn(proc() {
let mut buf: [u8, ..1024] = [0, ..1024];
loop {
let len = stream.read(buf);
tx2.send(Slc(len.unwrap(), buf));
}
})
}
}
}
}
以上代码无法编译:
Compiling chat v0.1.0 (file:///home/chris/rust/chat)
src/chat.rs:20:13: 20:29 error: the type of this value must be known in this context
src/chat.rs:20 Strm(mut stream) => {
^~~~~~~~~~~~~~~~
error: aborting due to previous error
Could not compile `chat`.
这是什么原因?
值的类型已知,它在enum
中声明为TcpStream
。
如何修复此代码?
答案 0 :(得分:8)
问题是,当您尝试与rx.recv()
匹配时,编译器不知道此表达式的类型,因为您使用泛型
let (tx, rx) = channel();
并且它无法推断出泛型类型。
另外,因为它必须检查您是否正确覆盖了模式,所以它无法使用模式本身来推断类型。因此,您需要明确声明它,如下所示:
let (tx, rx) = channel::<StreamOrSlice>();
答案 1 :(得分:1)
通过更改:
来解决此问题 match rx.recv() {
为:
let rxd: StreamOrSlice = rx.recv();
match rxd {
看起来这只是类型推断的失败。