2014-10-08 78 views
6

我在寫一個簡單的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

我該如何解決這段代碼?

回答

8

的問題是,當你試圖匹配rx.recv(),編譯器不知道這個表達式的類型,當你宣稱使用通用

let (tx, rx) = channel(); 

,它沒有可能性推斷泛型類型呢。

另外,因爲它必須檢查你是否正確地覆蓋了模式,所以它不能使用模式本身來推斷它的類型。您因此需要明確聲明,如下所示:

let (tx, rx) = channel::<StreamOrSlice>(); 
1

通過改變固定的:

 match rx.recv() { 

到:

 let rxd: StreamOrSlice = rx.recv(); 
     match rxd { 

看起來它只是類型推斷的失敗。