有STR :: as_bytes和G弦:: as_bytes with_nul之间的差异?

问题描述 投票:1回答:2

是否有这样做有什么区别:

name.as_bytes()

和这个:

CString::new(name)?.as_bytes_with_nul()

我想从name字节(这是String)的方式,我可以很容易地把他们在网络上,我不知道是否CString甚至必要在这里。

string rust
2个回答
5
投票

as_bytes_with_nul的文档开头:

相当于所不同的是所返回的切片包含拖尾NUL终止子的as_bytes功能。

虽然as_bytes是:

返回片不包含尾随空终止

(原帖强调)

这取决于你是否需要到NULL字节传输,这取决于你如何通过网络发送数据(TCP / UDP?通过TCP原始二进制数据?如果是这样,你怎么打算单独的邮件?JSON?等)。


1
投票

只要有你的字符串,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+0000which 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。

© www.soinside.com 2019 - 2024. All rights reserved.