我正在用自己的方式驾驶自己,因为根据文档判断它应该是无痛的:如何将字符串转换成一个字符串,&[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_slice
FWIW).该&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
.这可以避免堆分配.)