是否有这样做有什么区别:
name.as_bytes()
和这个:
CString::new(name)?.as_bytes_with_nul()
我想从name
字节(这是String
)的方式,我可以很容易地把他们在网络上,我不知道是否CString
甚至必要在这里。
as_bytes_with_nul
的文档开头:
相当于所不同的是所返回的切片包含拖尾NUL终止子的
as_bytes
功能。
虽然as_bytes
是:
返回片不包含尾随空终止
(原帖强调)
这取决于你是否需要到NULL字节传输,这取决于你如何通过网络发送数据(TCP / UDP?通过TCP原始二进制数据?如果是这样,你怎么打算单独的邮件?JSON?等)。
只要有你的字符串,0
没有name.as_bytes()
UTF-8编码单元和CString::new(name)?.as_bytes()
应该给你完全一样的字节。此外,CString
的.as_bytes_with_null()
只会追加0
字节。这是一个相当复杂的UTF-8串一个小演示:
use std::ffi::CString;
fn main() {
let message: String = "\nßщ\u{1F601}".to_string();
println!("bytes_1: {:?}", message.as_bytes());
println!("bytes_2: {:?}", CString::new(message.clone()).unwrap().as_bytes());
println!("bytes_3: {:?}", CString::new(message.clone()).unwrap().as_bytes_with_nul());
}
结果如预期(你可能认识的10
,对应于ASCII字符\n
,它以同样的方式编码的UTF-8):
bytes_1: [10, 195, 159, 209, 137, 240, 159, 152, 129]
bytes_2: [10, 195, 159, 209, 137, 240, 159, 152, 129]
bytes_3: [10, 195, 159, 209, 137, 240, 159, 152, 129, 0]
问题就出现了,如果你的字符串包含U+0000
,which is a valid Unicode code point,由0
一个UTF-8
字节编码,而在普通字符串可能发生。例如:
use std::ffi::CString;
fn main() {
let message: String = "\n\u{0000}\n\u{0000}".to_string();
println!("bytes_1: {:?}", message.as_bytes());
println!(
"bytes_2: {:?}",
match CString::new(message.clone()) {
Err(e) => format!("an error: {:?}, as expected", e),
Ok(_) => panic!("won't happen. .as_bytes() must fail."),
}
);
}
会给你
bytes_1: [10, 0, 10, 0]
bytes_2: "an error: NulError(1, [10, 0, 10, 0]), as expected"
因此,简单的.as_bytes()
成功,但CString
版本失败。我建议坚持name.as_bytes()
和UTF-8可能的话,没有理由先将其转换成一个CString。