str::as_bytes和CString::as_bytes_with_nul之间有区别吗?

str::as_bytes和CString::as_bytes_with_nul之间有区别吗?,string,rust,String,Rust,这样做有什么区别吗: name.as_bytes() 这是: CString::new(name)?.as_bytes_with_nul() 我想从名称中获取字节,该名称是字符串,我可以通过网络轻松发送它们,我不确定这里是否需要CString。的文档从以下内容开始: 与函数等效,但返回的片包含尾部nul终止符 虽然是: 返回的切片不包含尾部nul终止符 原文的重点 是否需要传输nul字节取决于您,这取决于您如何通过网络TCP/UDP发送数据?TCP上的原始二进制数据?如果是,您打算如何分离邮

这样做有什么区别吗:

name.as_bytes()
这是:

CString::new(name)?.as_bytes_with_nul()
我想从名称中获取字节,该名称是字符串,我可以通过网络轻松发送它们,我不确定这里是否需要CString。

的文档从以下内容开始:

与函数等效,但返回的片包含尾部nul终止符

虽然是:

返回的切片不包含尾部nul终止符

原文的重点

是否需要传输nul字节取决于您,这取决于您如何通过网络TCP/UDP发送数据?TCP上的原始二进制数据?如果是,您打算如何分离邮件?JSON?等等。

的文档从以下内容开始:

与函数等效,但返回的片包含尾部nul终止符

虽然是:

返回的切片不包含尾部nul终止符

原文的重点

是否需要传输nul字节取决于您,这取决于您如何通过网络TCP/UDP发送数据?TCP上的原始二进制数据?如果是,您打算如何分离邮件?JSON?etc..

只要字符串中没有0个UTF-8代码单元,name.As_字节和CString::newname?.As_字节应该为您提供完全相同的字节。此外,CString的.as\u bytes\u和\u 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]
如果字符串包含,由UTF-8中的单个0字节编码,并且可以在普通字符串中出现,则会出现问题。例如:

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"
因此,simple.as_字节成功,但CString版本失败。我建议坚持使用name.as_bytes和UTF-8,如果可能的话,没有理由先将其转换为CString。

只要字符串中没有0个UTF-8代码单元,name.as_bytes和CString::newname?。as_bytes应该给您完全相同的字节。此外,CString的.as\u bytes\u和\u 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]
如果字符串包含,由UTF-8中的单个0字节编码,并且可以在普通字符串中出现,则会出现问题。例如:

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"

因此,simple.as_字节成功,但CString版本失败。我建议坚持使用name.as_bytes和UTF-8,如果可能的话,没有理由先将其转换为CString。

我应该更仔细地查看文档。。。谢谢你的时间我应该仔细看一下这些文件。。。谢谢你抽出时间