我正在用自己的方式驾驶自己,因为根据文档判断它应该是无痛的:如何将字符串转换成一个字符串,&[u8]以便通过TCP或UDP将其发送到线路上?该bytes!()宏只出现对文字直接工作.
这是TCP应用程序的框架,完全来自其他来源.现在它作为回声服务器工作.我正在遇到的绊脚石是弄清楚如何在终端上打印&[u8]作为字符串,或者如何将字符串io::stdin().read_line()转换为&[u8]以通过电线发送,聊天风格.
这无法编译error: mismatched types: expected `&[u8]` but found `&str` (expected vector but found &str):
fn run_tcp_test_server(listen_addr: SocketAddr) {
    let mut acceptor = TcpListener::bind(listen_addr).listen().unwrap();
    println("[ INFO ] listener is ready.");
    loop {
        let stream = Cell::new(acceptor.accept().unwrap());
        do spawn {
            println("[ INFO ] got a request.");
            let mut stream = stream.take();
            let mut my_read_buff = ~[0, ..1024];
            match stream.read(my_read_buff) {
                Some(n) => {
                    stream.write(my_read_buff.slice_to(n));
                },
                _ => ()
            }
            let out_msg = "Hello World\r\n";
            stream.write(out_msg);
        }
    }
}
我也不认为let mut my_read_buff = ~[0, ..1024]可能是正确的,这似乎是C风格的溢出等待发生,我认为Rust应该修复.
我敢用这种困惑,我的理解是,&str是&[u8],我得到的类型系统陷入僵局,但不能让过去这一点.我试图从不std::str::raw安全的块中实现一些功能,但也没有运气.
&str具有相同的表示&[u8],但它有一个额外的不变量:内容始终是有效的UTF-8,因此它不是相同的类型,即你必须在它们之间明确地"转换"(有点类似于u8和i8具有相同的表示但需要明确的演员才能使用它们.这种"演员"是.as_bytes()从&str→开始&[u8],而std::str::from_utf8在另一个方向(在0.8,反向演员是from_utf8_sliceFWIW).该&str→ &[u8]投是非常,非常便宜; 优化它实际上是零成本(另一个方向必须检查有效的UTF-8,因此是O(n)),并且关闭它仍然是对一个具有非常少量的函数的函数调用说明.
因此,您需要:
stream.write(out_msg.as_bytes());
(如果out_msg始终是相同的消息,您实际上可以使用b前缀来获取编译时字节文字:
stream.write(b"Hello World\r\n")
)
我也不认为let mut my_read_buff =〜[0,..1024]可能是正确的,这似乎是C风格的溢出等待发生,我认为Rust应该修复.
不,矢量和切片的长度存储在其中,因此.read调用知道允许填充多少空间,并且不会/不能写入超出它的末尾.
(FWIW,如果你的缓冲区总是一个固定的长度,你可以删除~,即let mut my_read_buff = [0, ..1024];,所以my_read_buf将有类型[u8, .. 1024],即1024的固定长度向量u8.这可以避免堆分配.)