当前位置: 首页 > 知识库问答 >
问题:

Vec中的数据总是密集的吗?

岳玉堂
2023-03-14

看到这个生锈的“快捷方式”代码是一种常见的模式:

unsafe fn any_as_u8_slice<T: Sized>(p: &T) -> &[u8] {
    ::std::slice::from_raw_parts(
        (p as *const T) as *const u8,
        ::std::mem::size_of::<T>(),
    )
}

例如,给定一个结构,不安全地将底层指针转换为

然而,当使用Vec时,采用相同的方法有效吗

例如,这似乎是可行的:

use std::mem::size_of;
use std::slice::from_raw_parts;

#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct Point {
    pub x: u8,
    pub y: u8,
    pub z: u8,
}


fn as_bytes(data: &[Point]) -> &[u8] {
    unsafe { 
        let raw_pointer = data.as_ptr();
        from_raw_parts(raw_pointer as *const u8, size_of::<Point>() * data.len())
    }
}

fn main() {
    let points = vec![Point{x: 0u8, y: 1u8, z: 2u8}, Point{x: 3u8, y: 4u8, z: 5u8}];
    let slice = points.as_slice();
    println!("{:?}", slice);

    let bytes = as_bytes(slice);
    println!("{:?}", bytes);
    
    assert!(bytes.len() == 6);
    assert!(bytes[0] == 0u8);
    assert!(bytes[1] == 1u8);
    assert!(bytes[2] == 2u8);
    assert!(bytes[3] == 3u8);
    assert!(bytes[4] == 4u8);
    assert!(bytes[5] == 5u8);
}

...但是假设Vec可靠吗

关于https://doc.rust-lang.org/std/vec/struct.Vec.html#capacity-再分配说:

如果一个Vec已经分配了内存,那么它指向的内存在堆上(根据分配器Rust的定义,默认情况下配置为使用),它的指针依次指向len初始化的连续元素(如果将其强制为一个片,就会看到),然后是逻辑上未初始化的连续元素的容量len。

...但我不确定我是否理解这意味着什么。这是否意味着对于Vec


共有1个答案

宣煜
2023-03-14

是的,一个Vec

这里有一个警告,因为你真正感兴趣的是T切片,这是Vec可以提供的;Vec本身应被视为一个实现细节。除此之外:

>

Rust参考定义了切片与它们切片的数组的部分具有相同的布局。所以当我们从一个Vec

Rust引用定义了数组的内存布局:

数组的布局使数组的第n个元素从数组的开头偏移n*类型字节的大小。[T; n]的数组的大小为size_of::

我们知道n(来自[T]),我们知道“类型的大小字节”(通过mem::size\u of

为了充分利用这一切,你应该确保你得到了Vecslice,首先在slice上使用as_ptr(),然后投射你得到的原始指针。这确保了上述定义的顺序。您的fn为_字节(数据:

 类似资料:
  • 这里我将vec分割成大小相等的4个子向量,然后返回一个集合,我希望从集合中返回的类型是< code>Vec

  • 在第七章我们粗略介绍了一下Vec的用法。实际上,作为Rust中一个非常重要的数据类型,熟练掌握Vec的用法能大大提升我们在Rust世界中的编码能力。 特性及声明方式 和我们之前接触到的Array不同,Vec具有动态的添加和删除元素的能力,并且能够以O(1)的效率进行随机访问。同时,对其尾部进行push或者pop操作的效率也是平摊O(1)的。 同时,有一个非常重要的特性(虽然我们编程的时候大部分都不

  • 随着应用程序的改进,我希望加密XML文件,以防止用户查看内部(其中有一堆数据,但应用程序根据分配给用户的访问级别有选择地显示数据)。我研究了“Rijndael Managed”,得到了一个基于VB.NET中加密/解密文件的原型。我不知道如何将一个流传递给加密类而不将它们保存到磁盘中。 现在,我将xml文件从Dataset中保存到一个临时目录中,构造一个新的流并将其传递给CrypotoStream,

  • vec

    描述 (Description) 此函数使用指定EXPR的字符串作为无符号整数的向量。 NUMBITS参数是为位向量中的每个条目保留的位数。 这必须是从1到32的2的幂。请注意,偏移量是向量结束的标记,它会计算指定的位数以查找开始。 可以使用逻辑按位运算符|,&和^来操纵向量。 语法 (Syntax) 以下是此函数的简单语法 - vec EXPR, OFFSET, BITS 返回值 (Retur

  • 问题内容: 当我仔细观察时,我唯一提出的疑问是: 找不到适用于实际参数“ org.apache.spark.unsafe.types.UTF8String”的适用构造函数/方法;候选者为:“ public void sparkSQL.Tweet.setId(long)” 问题答案: 正如@ user9718686所写,id字段具有不同的类型:在json文件和类定义中。当您将其读入时,Spark会从

  • 我正在评估将现有的RDD代码替换为Dataset。对于我的一个用例,我无法将数据集映射到另一个用例类。 以下是我想做的。。。 任何帮助都将不胜感激。 但以下例外情况: