我用这个来驱动自己疯狂,因为根据文档判断它应该是无痛的:我如何将字符串转换为&[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
的一些功能,但也没有运气。
答案 0 :(得分:7)
&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
的长度向量。这可以避免堆分配。)