Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rust 如何切片大型Vec<;i32>;as&;[u8]?_Rust - Fatal编程技术网

Rust 如何切片大型Vec<;i32>;as&;[u8]?

Rust 如何切片大型Vec<;i32>;as&;[u8]?,rust,Rust,我不知道如何将Vec转换为和[u8]切片 fn main() { let v: Vec<i32> = vec![1; 100_000_000]; let v_bytes: &[u8] = /* ... */; } fn main(){ 让v:Vec=Vec![1;100_000_000]; 设v_字节:&[u8]=/*…*/; } 我想将一个大的Vec写入一个文件,以便将来可以将其读回。您可以使用: 让v_字节:&[u8]=不安全{ 标准::切片::来自原

我不知道如何将
Vec
转换为
和[u8]
切片

fn main() {
    let v: Vec<i32> = vec![1; 100_000_000];
    let v_bytes: &[u8] = /* ... */;
}
fn main(){
让v:Vec=Vec![1;100_000_000];
设v_字节:&[u8]=/*…*/;
}
我想将一个大的
Vec
写入一个文件,以便将来可以将其读回。

您可以使用:

让v_字节:&[u8]=不安全{
标准::切片::来自原始零件(
v、 as_ptr()as*const u8,
v、 len()*std::mem::size_of::(),
)
};
根据此答案的注释,您应该将此代码包装在函数中,并让返回值借用输入,以便尽可能使用借用检查器:

fn as_u8_slice(v: &[i32]) -> &[u8] {
    unsafe {
        std::slice::from_raw_parts(
            v.as_ptr() as *const u8,
            v.len() * std::mem::size_of::<i32>(),
        )
    }
}
fn作为u8切片(v:&i32])->&u8]{
不安全{
标准::切片::来自原始零件(
v、 as_ptr()as*const u8,
v、 len()*std::mem::size_of::(),
)
}
}

由于Rust 1.30,最好的解决方案是使用:


我尝试过使用mem::transmute,但没有成功。如果要将数据写入文件,应该使用编码。或者我自己的也可以。您是否担心这些数据在计算机或软件版本之间的endian性或可移植性?我不担心可移植性,因为它将始终位于固定的小型endian linux x86服务器上。将其封装在函数中,并将返回值借用输入vec,以便尽可能使用借用检查器
unsafe fn as_u8_slice(xs:&[i32])->&[u8]{…
您真的应该以某种方式限制slice的生存期参数。前面的评论者的建议看起来是最好的方法。您的函数不应该被标记为
unsafe
,因为它公开了一个完全安全的接口。没问题,我已经修复了它。
fn as_u8_slice(v: &[i32]) -> &[u8] {
    unsafe {
        std::slice::from_raw_parts(
            v.as_ptr() as *const u8,
            v.len() * std::mem::size_of::<i32>(),
        )
    }
}
fn main() {
    let v: Vec<i32> = vec![1; 8];

    let (head, body, tail) = unsafe { v.align_to::<u8>() };
    assert!(head.is_empty());
    assert!(tail.is_empty());

    println!("{:#x?}", body);
}
use std::fs::File;
use std::io::{Read, Write};
use std::{mem, slice};

fn as_u8_slice(v: &[i32]) -> &[u8] {
    let element_size = mem::size_of::<i32>();
    unsafe { slice::from_raw_parts(v.as_ptr() as *const u8, v.len() * element_size) }
}

fn from_u8(v: Vec<u8>) -> Vec<i32> {
    let data = v.as_ptr();
    let len = v.len();
    let capacity = v.capacity();
    let element_size = mem::size_of::<i32>();

    // Make sure we have a proper amount of capacity (may be overkill)
    assert_eq!(capacity % element_size, 0);
    // Make sure we are going to read a full chunk of stuff
    assert_eq!(len % element_size, 0);

    unsafe {
        // Don't allow the current vector to be dropped
        // (which would invalidate the memory)
        mem::forget(v);

        Vec::from_raw_parts(
            data as *mut i32,
            len / element_size,
            capacity / element_size,
        )
    }
}

fn do_write(filename: &str, v: &[i32]) {
    let mut f = File::create(filename).unwrap();
    f.write_all(as_u8_slice(v)).unwrap();
}

fn do_read(filename: &str) -> Vec<i32> {
    let mut f = File::open(filename).unwrap();
    let mut bytes = Vec::new();

    f.read_to_end(&mut bytes).unwrap();

    from_u8(bytes)
}

fn main() {
    let v = vec![42; 10];
    do_write("vector.dump", &v);
    let v2 = do_read("vector.dump");

    assert_eq!(v, v2);
    println!("{:?}", v2)
}