是否可以通过引用返回结构的一部分?

时间:2016-06-13 21:30:26

标签: struct reference rust

考虑以下两个结构:

pub struct BitVector<S: BitStorage> {
    data: Vec<S>,
    capacity: usize,
    storage_size: usize
}

pub struct BitSlice<'a, S: BitStorage> {
    data: &'a [S],
    storage_size: usize
}

其中BitStorage实际上是一种仅限于所有无符号整数的类型(u8,u16,u32,u64,usize)。

如何实施Deref特质? (BitVector<S> derefs to BitSlice<S>类似于Vec<S> derefs to &[S]的方式

我尝试了以下内容(请注意,由于生命周期问题,它不会编译,但更重要的是因为我尝试在堆栈上返回一个值作为参考):

impl<'b, S: BitStorage> Deref for BitVector<S> {
    type Target = BitSlice<'b, S>;

    fn deref<'a>(&'a self) -> &'a BitSlice<'b, S> {
        let slice = BitSlice {
            data: self.data,
            storage_size: self.storage_size,
        };
        &slice
    }
}

我知道可以通过引用返回结构的字段,所以例如我可以在&Vec<S>特征中返回&usizeDeref,但是可能吗?要返回BitSlice,请注意我基本上已将BitVector中已包含Vec<S>的所有数据转换为&[S]storage_size已存在?< / p>

我认为如果我可以使用两个值创建一个结构并且以某种方式告诉编译器忽略它是在堆栈上创建的结构而不是仅使用现有值的事实,这是可能的,但我有不知道怎么做。

1 个答案:

答案 0 :(得分:2)

Deref需要返回引用。引用始终指向某些现有内存,并且任何局部变量都不会存在足够长的时间。从理论上讲,你可以在deref中创建一个新对象并返回对它的引用,但是我所知道的所有这些都会导致内存泄漏。让我们忽略这些技术细节,并说它根本不可能。

现在怎样?您必须更改API。 Vec可以实施Deref,因为它可以解除[T],而不是&[T]或类似的任何内容。您可以使用相同的策略取得成功:使BitSlice<S>成为仅包含切片[S]的未大小类型,以便返回类型为&'a BitSlice<S>。这假设不需要storage_size成员。但似乎这是指逻辑上有效的位数(即,可以在不扩展位向量的情况下访问) - 如果是这样,那似乎是不可避免的 1

另一种选择当然是不实施Deref。不方便,但如果切片数据类型与实际切片相距太远,则可能是唯一的选择。

RFC PR #1524建议自定义动态大小的类型,然后您可以使用类似于切片的BitSlice<S>类型,但可以包含其他内容,例如storage_size。然而,这还没有存在,如果它永远存在,它还远未确定。

1 然而,capacity上的BitVector成员似乎毫无意义。那不仅仅是sizeof S * 8吗?