我正在用这个让自己疯狂,因为从文档来看它应该是无痛的:如何将字符串转换为 &[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")
)
不,向量和切片的长度存储在其中,因此
.read
调用知道允许填充多少空间,并且不会/不能写入超出它的末尾。(FWIW,如果您的缓冲区始终是固定长度,您可以删除
~
,即 let mut my_read_buff = [0, ..1024];
,因此 my_read_buf
将具有类型 [u8, .. 1024]
,即 1024 u8
的固定长度向量。这避免了堆分配。)关于tcp - 访问 &str 作为 &[u8],我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20891327/