访问&str as&[u8]

isp*_*ava 4 tcp rust

我正在用自己的方式驾驶自己,因为根据文档判断它应该是无痛的:如何将字符串转换成一个字符串,&[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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我也不认为let mut my_read_buff = ~[0, ..1024]可能是正确的,这似乎是C风格的溢出等待发生,我认为Rust应该修复.

我敢用这种困惑,我的理解是,&str&[u8],我得到的类型系统陷入僵局,但不能让过去这一点.我试图从不std::str::raw安全的块中实现一些功能,但也没有运气.

huo*_*uon 7

&str具有相同的表示&[u8],但它有一个额外的不变量:内容始终是有效的UTF-8,因此它不是相同的类型,即你必须在它们之间明确地"转换"(有点类似于u8i8具有相同的表示但需要明确的演员才能使用它们.这种"演员"是.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());
Run Code Online (Sandbox Code Playgroud)

(如果out_msg始终是相同的消息,您实际上可以使用b前缀来获取编译时字节文字:

stream.write(b"Hello World\r\n")
Run Code Online (Sandbox Code Playgroud)

)


我也不认为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.这可以避免堆分配.)